[xiph-commits] r8691 - in trunk/oggdsf: build/oggcodecs sln/oggdsf_all src/lib/codecs/cmml src/lib/codecs/cmml/libCMMLParse src/tests/testCMMLParser

ozone at motherfish-iii.xiph.org ozone at motherfish-iii.xiph.org
Sat Jan 8 12:07:55 PST 2005


Author: ozone
Date: 2005-01-08 12:07:55 -0800 (Sat, 08 Jan 2005)
New Revision: 8691

Added:
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.cpp
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.h
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.c
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.h
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ReadMe.txt
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.cpp
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.h
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.vcproj
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.cpp
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.h
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.c
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.h
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.c
   trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.h
Modified:
   trunk/oggdsf/build/oggcodecs/oggcodecs.vdproj
   trunk/oggdsf/sln/oggdsf_all/oggdsf_all.sln
   trunk/oggdsf/src/tests/testCMMLParser/testCMMLParser.cpp
Log:
oggdsf:
 * Added libCMMLParse library, which isn't reliant on the Windows-only MSXML2 XML parser.  Still not completely working, but we're getting there ...
 * Switched testCMMLParser to use libCMMLParse instead of libWinCMMLParse
 * Added better test output to testCMMLParser


Modified: trunk/oggdsf/build/oggcodecs/oggcodecs.vdproj
===================================================================
--- trunk/oggdsf/build/oggcodecs/oggcodecs.vdproj	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/build/oggcodecs/oggcodecs.vdproj	2005-01-08 20:07:55 UTC (rev 8691)
@@ -21,6 +21,12 @@
         }
         "Entry"
         {
+        "MsmKey" = "8:_054BE8EA6F5E45A7AB2066734E998570"
+        "OwnerKey" = "8:_UNDEFINED"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
         "MsmKey" = "8:_0A1E63E5852E4F759F1A27E8F097727B"
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
@@ -51,6 +57,12 @@
         }
         "Entry"
         {
+        "MsmKey" = "8:_1FDED4DADD384431A22FF1C26BE42207"
+        "OwnerKey" = "8:_UNDEFINED"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
         "MsmKey" = "8:_24A1793CB89A464FB683A8A3BDA774DB"
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
@@ -105,19 +117,25 @@
         }
         "Entry"
         {
-        "MsmKey" = "8:_42F89A4130A36CD4BA74B00F4B424775"
-        "OwnerKey" = "8:_8F970C0B2593413CA2A3BBF5F2600387"
+        "MsmKey" = "8:_46A378A9B03E4612A645053EDB884C20"
+        "OwnerKey" = "8:_02E7D9728C8944F1BD021329177F5140"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
         "MsmKey" = "8:_46A378A9B03E4612A645053EDB884C20"
-        "OwnerKey" = "8:_02E7D9728C8944F1BD021329177F5140"
+        "OwnerKey" = "8:_054BE8EA6F5E45A7AB2066734E998570"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
         "MsmKey" = "8:_46A378A9B03E4612A645053EDB884C20"
+        "OwnerKey" = "8:_1FDED4DADD384431A22FF1C26BE42207"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
+        "MsmKey" = "8:_46A378A9B03E4612A645053EDB884C20"
         "OwnerKey" = "8:_FD547F0196C24DFBB9CAFCCEC06561BC"
         "MsmSig" = "8:_UNDEFINED"
         }
@@ -363,6 +381,12 @@
         }
         "Entry"
         {
+        "MsmKey" = "8:_5A4EFEBB52DC88AE0DABDEE219328F5C"
+        "OwnerKey" = "8:_DB60960DC12343B89500B86D5AB10D02"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
         "MsmKey" = "8:_5EB08DD30B564283AA9C9F27D80CF9E4"
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
@@ -388,12 +412,18 @@
         "Entry"
         {
         "MsmKey" = "8:_655D5383153A6AB10D15352A7EABCC7A"
-        "OwnerKey" = "8:_E4B8E67DA0E54BB3BB025BFCF536BF3B"
+        "OwnerKey" = "8:_054BE8EA6F5E45A7AB2066734E998570"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
         "MsmKey" = "8:_655D5383153A6AB10D15352A7EABCC7A"
+        "OwnerKey" = "8:_1FDED4DADD384431A22FF1C26BE42207"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
+        "MsmKey" = "8:_655D5383153A6AB10D15352A7EABCC7A"
         "OwnerKey" = "8:_FD547F0196C24DFBB9CAFCCEC06561BC"
         "MsmSig" = "8:_UNDEFINED"
         }
@@ -418,6 +448,12 @@
         "Entry"
         {
         "MsmKey" = "8:_655D5383153A6AB10D15352A7EABCC7A"
+        "OwnerKey" = "8:_E4B8E67DA0E54BB3BB025BFCF536BF3B"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
+        "MsmKey" = "8:_655D5383153A6AB10D15352A7EABCC7A"
         "OwnerKey" = "8:_E1E372FA955046E6928BF533EA0AE6C3"
         "MsmSig" = "8:_UNDEFINED"
         }
@@ -693,18 +729,6 @@
         }
         "Entry"
         {
-        "MsmKey" = "8:_B2784574F1B848EABBE013669B46808C"
-        "OwnerKey" = "8:_DB60960DC12343B89500B86D5AB10D02"
-        "MsmSig" = "8:_UNDEFINED"
-        }
-        "Entry"
-        {
-        "MsmKey" = "8:_B6A0B75A2A7A47922297CCEFC5F6F6BA"
-        "OwnerKey" = "8:_3243E453AFD94BB88B5A1014BDFCBAAE"
-        "MsmSig" = "8:_UNDEFINED"
-        }
-        "Entry"
-        {
         "MsmKey" = "8:_B9749E2A902A46BEAE555C07E32980BB"
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
@@ -931,10 +955,10 @@
             "IsDependency" = "11:FALSE"
             "IsolateTo" = "8:"
             }
-            "{A582A373-4685-4296-BEFE-614B80A702C3}:_42F89A4130A36CD4BA74B00F4B424775"
+            "{A582A373-4685-4296-BEFE-614B80A702C3}:_46A378A9B03E4612A645053EDB884C20"
             {
-            "SourcePath" = "8:dsfOggDemux.dll"
-            "TargetName" = "8:dsfOggDemux.dll"
+            "SourcePath" = "8:MSVCP71D.dll"
+            "TargetName" = "8:MSVCP71D.dll"
             "Tag" = "8:"
             "Folder" = "8:_371AD289B6DB4693BDF7568485051F1E"
             "Condition" = "8:"
@@ -947,14 +971,14 @@
             "SharedLegacy" = "11:FALSE"
             "PackageAs" = "3:1"
             "Register" = "3:1"
-            "Exclude" = "11:TRUE"
+            "Exclude" = "11:FALSE"
             "IsDependency" = "11:TRUE"
             "IsolateTo" = "8:"
             }
-            "{A582A373-4685-4296-BEFE-614B80A702C3}:_46A378A9B03E4612A645053EDB884C20"
+            "{A582A373-4685-4296-BEFE-614B80A702C3}:_5752F7DAA54F2A09A6DC1D6BEB922BDD"
             {
-            "SourcePath" = "8:MSVCP71D.dll"
-            "TargetName" = "8:MSVCP71D.dll"
+            "SourcePath" = "8:WSOCK32.dll"
+            "TargetName" = "8:WSOCK32.dll"
             "Tag" = "8:"
             "Folder" = "8:_371AD289B6DB4693BDF7568485051F1E"
             "Condition" = "8:"
@@ -967,14 +991,14 @@
             "SharedLegacy" = "11:FALSE"
             "PackageAs" = "3:1"
             "Register" = "3:1"
-            "Exclude" = "11:FALSE"
+            "Exclude" = "11:TRUE"
             "IsDependency" = "11:TRUE"
             "IsolateTo" = "8:"
             }
-            "{A582A373-4685-4296-BEFE-614B80A702C3}:_5752F7DAA54F2A09A6DC1D6BEB922BDD"
+            "{A582A373-4685-4296-BEFE-614B80A702C3}:_5A4EFEBB52DC88AE0DABDEE219328F5C"
             {
-            "SourcePath" = "8:WSOCK32.dll"
-            "TargetName" = "8:WSOCK32.dll"
+            "SourcePath" = "8:libFLAC.dll"
+            "TargetName" = "8:libFLAC.dll"
             "Tag" = "8:"
             "Folder" = "8:_371AD289B6DB4693BDF7568485051F1E"
             "Condition" = "8:"
@@ -1051,46 +1075,6 @@
             "IsDependency" = "11:FALSE"
             "IsolateTo" = "8:"
             }
-            "{A582A373-4685-4296-BEFE-614B80A702C3}:_B2784574F1B848EABBE013669B46808C"
-            {
-            "SourcePath" = "8:libFLAC.dll"
-            "TargetName" = "8:libFLAC.dll"
-            "Tag" = "8:"
-            "Folder" = "8:_371AD289B6DB4693BDF7568485051F1E"
-            "Condition" = "8:"
-            "Transitive" = "11:FALSE"
-            "Vital" = "11:TRUE"
-            "ReadOnly" = "11:FALSE"
-            "Hidden" = "11:FALSE"
-            "System" = "11:FALSE"
-            "Permanent" = "11:FALSE"
-            "SharedLegacy" = "11:FALSE"
-            "PackageAs" = "3:1"
-            "Register" = "3:1"
-            "Exclude" = "11:TRUE"
-            "IsDependency" = "11:TRUE"
-            "IsolateTo" = "8:"
-            }
-            "{A582A373-4685-4296-BEFE-614B80A702C3}:_B6A0B75A2A7A47922297CCEFC5F6F6BA"
-            {
-            "SourcePath" = "8:libOOOgg.dll"
-            "TargetName" = "8:libOOOgg.dll"
-            "Tag" = "8:"
-            "Folder" = "8:_371AD289B6DB4693BDF7568485051F1E"
-            "Condition" = "8:"
-            "Transitive" = "11:FALSE"
-            "Vital" = "11:TRUE"
-            "ReadOnly" = "11:FALSE"
-            "Hidden" = "11:FALSE"
-            "System" = "11:FALSE"
-            "Permanent" = "11:FALSE"
-            "SharedLegacy" = "11:FALSE"
-            "PackageAs" = "3:1"
-            "Register" = "3:1"
-            "Exclude" = "11:TRUE"
-            "IsDependency" = "11:TRUE"
-            "IsolateTo" = "8:"
-            }
             "{A582A373-4685-4296-BEFE-614B80A702C3}:_D9BE90D398094F15B881B22369C3A231"
             {
             "SourcePath" = "8:..\\..\\VERSIONS"
@@ -1167,7 +1151,7 @@
         "Name" = "8:Microsoft Visual Studio"
         "ProductName" = "8:oggcodecs"
         "ProductCode" = "8:{D65F0073-A820-4085-B997-A061171595A7}"
-        "PackageCode" = "8:{F5412C16-1C4F-47F4-BED4-C24C25AA1AFF}"
+        "PackageCode" = "8:{50255F27-890C-447B-889C-879484843EDF}"
         "UpgradeCode" = "8:{1A644FEB-7597-4FAB-AADE-C2C7C64C5984}"
         "RestartWWWService" = "11:FALSE"
         "RemovePreviousVersions" = "11:TRUE"
@@ -3321,6 +3305,34 @@
                 {
                 }
             }
+            "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_054BE8EA6F5E45A7AB2066734E998570"
+            {
+            "SourcePath" = "8:..\\..\\src\\lib\\helper\\libOOOggChef\\Debug\\libOOOggChef.dll"
+            "TargetName" = "8:"
+            "Tag" = "8:"
+            "Folder" = "8:_371AD289B6DB4693BDF7568485051F1E"
+            "Condition" = "8:"
+            "Transitive" = "11:FALSE"
+            "Vital" = "11:TRUE"
+            "ReadOnly" = "11:FALSE"
+            "Hidden" = "11:FALSE"
+            "System" = "11:FALSE"
+            "Permanent" = "11:FALSE"
+            "SharedLegacy" = "11:FALSE"
+            "PackageAs" = "3:1"
+            "Register" = "3:1"
+            "Exclude" = "11:FALSE"
+            "IsDependency" = "11:FALSE"
+            "IsolateTo" = "8:"
+            "ProjectOutputGroupRegister" = "3:1"
+            "OutputConfiguration" = "8:"
+            "OutputGroupCanonicalName" = "8:Built"
+            "OutputProjectGuid" = "8:{3D55194E-6732-4A74-A947-EDFF585A0F19}"
+            "ShowKeyOutput" = "11:TRUE"
+                "ExcludeFilters"
+                {
+                }
+            }
             "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_0A1E63E5852E4F759F1A27E8F097727B"
             {
             "SourcePath" = "8:..\\..\\src\\tools\\OOOggDump\\Debug\\OOOggDump.exe"
@@ -3433,6 +3445,34 @@
                 {
                 }
             }
+            "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_1FDED4DADD384431A22FF1C26BE42207"
+            {
+            "SourcePath" = "8:..\\..\\src\\lib\\codecs\\cmml\\libcmmlparse\\debug\\libCMMLParse.dll"
+            "TargetName" = "8:"
+            "Tag" = "8:"
+            "Folder" = "8:_371AD289B6DB4693BDF7568485051F1E"
+            "Condition" = "8:"
+            "Transitive" = "11:FALSE"
+            "Vital" = "11:TRUE"
+            "ReadOnly" = "11:FALSE"
+            "Hidden" = "11:FALSE"
+            "System" = "11:FALSE"
+            "Permanent" = "11:FALSE"
+            "SharedLegacy" = "11:FALSE"
+            "PackageAs" = "3:1"
+            "Register" = "3:1"
+            "Exclude" = "11:FALSE"
+            "IsDependency" = "11:FALSE"
+            "IsolateTo" = "8:"
+            "ProjectOutputGroupRegister" = "3:1"
+            "OutputConfiguration" = "8:"
+            "OutputGroupCanonicalName" = "8:Built"
+            "OutputProjectGuid" = "8:{899EB7AD-26BF-4495-9BE5-EADECCC288B2}"
+            "ShowKeyOutput" = "11:TRUE"
+                "ExcludeFilters"
+                {
+                }
+            }
             "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_24A1793CB89A464FB683A8A3BDA774DB"
             {
             "SourcePath" = "8:..\\..\\src\\lib\\codecs\\vorbis\\libs\\libvorbis\\win32\\Vorbis_Dynamic_Debug\\vorbis_d.dll"

Modified: trunk/oggdsf/sln/oggdsf_all/oggdsf_all.sln
===================================================================
--- trunk/oggdsf/sln/oggdsf_all/oggdsf_all.sln	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/sln/oggdsf_all/oggdsf_all.sln	2005-01-08 20:07:55 UTC (rev 8691)
@@ -1069,7 +1069,7 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testCMMLParser", "..\..\src\tests\testCMMLParser\testCMMLParser.vcproj", "{BF72BA81-0735-46FB-8C8C-E36758477756}"
 	ProjectSection(ProjectDependencies) = postProject
-		{23BAAF7B-AEC3-4812-AA91-7E5061E83A39} = {23BAAF7B-AEC3-4812-AA91-7E5061E83A39}
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2} = {899EB7AD-26BF-4495-9BE5-EADECCC288B2}
 		{AD38DCC6-B431-4B32-8569-74F3376EF2DA} = {AD38DCC6-B431-4B32-8569-74F3376EF2DA}
 	EndProjectSection
 EndProject
@@ -1165,6 +1165,12 @@
 		{2DA569EC-3E22-4BC9-A242-C7A56EB9C6F4} = {2DA569EC-3E22-4BC9-A242-C7A56EB9C6F4}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCMMLParse", "..\..\src\lib\codecs\cmml\libCMMLParse\libCMMLParse.vcproj", "{899EB7AD-26BF-4495-9BE5-EADECCC288B2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{AD38DCC6-B431-4B32-8569-74F3376EF2DA} = {AD38DCC6-B431-4B32-8569-74F3376EF2DA}
+		{2DA569EC-3E22-4BC9-A242-C7A56EB9C6F4} = {2DA569EC-3E22-4BC9-A242-C7A56EB9C6F4}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfiguration) = preSolution
 		Debug = Debug
@@ -2614,6 +2620,26 @@
 		{1D3F3520-FD46-4C72-B2AA-A917AB368053}.Release_SSE.Build.0 = Release|Win32
 		{1D3F3520-FD46-4C72-B2AA-A917AB368053}.Release_SSE2.ActiveCfg = Release|Win32
 		{1D3F3520-FD46-4C72-B2AA-A917AB368053}.Release_SSE2.Build.0 = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Debug.ActiveCfg = Debug|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Debug.Build.0 = Debug|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Debug Unicode.ActiveCfg = Debug|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Debug Unicode.Build.0 = Debug|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Debug__cdecl.ActiveCfg = Debug|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Debug__cdecl.Build.0 = Debug|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.MakeFile.ActiveCfg = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.MakeFile.Build.0 = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release.ActiveCfg = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release.Build.0 = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release Unicode.ActiveCfg = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release Unicode.Build.0 = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release__cdecl.ActiveCfg = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release__cdecl.Build.0 = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release_NoDotNET.ActiveCfg = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release_NoDotNET.Build.0 = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release_SSE.ActiveCfg = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release_SSE.Build.0 = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release_SSE2.ActiveCfg = Release|Win32
+		{899EB7AD-26BF-4495-9BE5-EADECCC288B2}.Release_SSE2.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionItems) = postSolution
 	EndGlobalSection

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.cpp	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.cpp	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,509 @@
+//===========================================================================
+//Copyright (C) 2005 Zentaro Kavanagh
+//
+//Copyright (C) 2005 Commonwealth Scientific and Industrial Research
+//                   Organisation (CSIRO) Australia
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+
+#include <libCMMLParse/CMMLParser.h>
+#include <libCMMLParse/xtag.h>
+
+#include <libCMMLTags/libCMMLTags.h>
+#include <libilliCore/StringHelper.h>
+
+#include <fstream>
+#include <iostream>
+
+using namespace std;
+
+// TODO: Properly parse preamble
+// TODO: i18n?
+// TODO: Macrofy non-macrofied bits.  Woo macros!
+// TODO: Do actual memory management :}
+
+// Macros are evil, macros are evil, can't sleep, clown'll eat me ...
+
+#define XTAG_PARSE_INTO(tagParser, parseMethod, TagType, parentTagSetter, parentTag) \
+	{ \
+		TagType *locTag = new TagType; \
+		if (!parseMethod(tagParser, locTag)) { \
+			return false; \
+		} \
+		parentTag->parentTagSetter(locTag); \
+		/* delete locTag; */ \
+	};
+
+#define XTAG_SET_ATTRIBUTE(tagParser, attributeName, tag, attributeSetter) \
+	{ \
+		const char *locAttributeCString = xtag_get_attribute(tagParser, attributeName); \
+		if (locAttributeCString) { \
+			tag->attributeSetter(StringHelper::toWStr(locAttributeCString)); \
+			/* free((void *) locAttributeCString); */ \
+		} \
+	};
+
+#define XTAG_REQUIRED_ATTRIBUTE(tagParser, attributeName, tag) \
+	{ \
+		const char *locAttributeCString = xtag_get_attribute(tagParser, attributeName); \
+		if (!locAttributeCString) { \
+			cout << "Failed 3" << endl; \
+			return false; \
+		} else { \
+			/* free((void *) locAttributeCString); */ \
+		} \
+	};
+
+#define XTAG_PARSE_CHILD(parentParser, tagName, tagParser, tagType, setterMethod, parentTag) \
+	{ \
+		XTag *locParser = NULL; \
+		locParser = xtag_first_child(parentParser, tagName); \
+		if (locParser) { \
+			XTAG_PARSE_INTO(locParser, tagParser, tagType, setterMethod, parentTag); \
+		} \
+	};
+
+#define XTAG_EXACTLY_ONE_CHILD(parentParser, tagName) \
+	{ \
+		XTag *locParser = xtag_first_child(parentParser, tagName); \
+		if (locParser != NULL) { \
+			/* Found at least one child */ \
+			locParser = xtag_next_child(parentParser, tagName); \
+			if (locParser) { \
+				/* Danger will robinson, found more than one child */ \
+				cout << "Failed 1" << endl; \
+				return false; \
+			} \
+		} else { \
+			/* Found no child */ \
+			cout << "Failed 2" << endl; \
+			return false; \
+		} \
+	};
+
+#define XTAG_PARSE_LIST(TagType, listTagName, tagParser, parentParser, parentTag, parentGetListMethod) \
+	{ \
+		XTag *locTagListParser = NULL; \
+		for (	locTagListParser = xtag_first_child(parentParser, listTagName); \
+				locTagListParser != NULL; \
+				locTagListParser = xtag_next_child(parentParser, listTagName)) { \
+			XTAG_PARSE_INTO(locTagListParser, tagParser, TagType, addTag, parentTag->parentGetListMethod()); \
+		} \
+	};
+
+#define XTAG_SET_CDATA(tagParser, tag) \
+	{ \
+		const char *locCData = xtag_get_pcdata(tagParser); \
+		if (locCData) { \
+			tag->setText(StringHelper::toWStr(locCData)); \
+			/* free((void *) locCData); */ \
+		} \
+	};
+
+
+CMMLParser::CMMLParser(void)
+{
+}
+
+CMMLParser::~CMMLParser(void)
+{
+}
+
+bool CMMLParser::parseDocFromFile(wstring inFilename, C_CMMLDoc* outCMMLDoc)
+{
+	// Assume we are unsuccessful unless we explicitly change that
+
+	bool locReturnValue = false;
+
+	// Sanity check against a NULL output pointer
+	if (!outCMMLDoc) {
+		return false;
+	}
+
+	// Somebody set us up our file!
+
+	fstream locFile;
+
+	locFile.open(StringHelper::toNarrowStr(inFilename).c_str(),
+		ios_base::in | ios_base::binary);
+
+	// Look ma, the world's most portable file-size-getting-function-thing
+	locFile.seekg(0, ios::end);
+	size_t locCMMLFileSize = locFile.tellg();
+
+	// Read the entirety of the file into the buffer
+	locFile.clear();
+	locFile.seekg(0);
+
+	unsigned short BUFFER_SIZE = 8192;
+	char *locBuffer = new char[locCMMLFileSize];
+	size_t locBytesRead = 0;
+
+	while (!locFile.eof()) {
+		locFile.read(locBuffer + locBytesRead, BUFFER_SIZE);
+		locBytesRead = locFile.gcount();
+	}
+
+	locFile.close();
+
+	// Widen the file stream
+	wstring locCMMLFileWString = StringHelper::toWStr(locBuffer);
+
+	// Parse ourselves the CMML
+	C_CMMLRootTag* locRootTag = new C_CMMLRootTag;
+	locReturnValue = parseCMMLRootTag(locCMMLFileWString, locRootTag);
+	if (locReturnValue) {
+		// Successfully parsed the CMML
+		outCMMLDoc->setRoot(locRootTag);
+	} else {
+		// Parsing CMML failed
+		outCMMLDoc = NULL;
+	}
+
+	// Clean up
+	//delete locRootTag;
+	//delete [] locBuffer;
+
+	return locReturnValue;
+}
+
+
+bool CMMLParser::parseCMMLRootTag(wstring inCMMLRootText, C_CMMLRootTag* outCMMLRoot)
+{
+	// Assume we are unsuccessful unless we explicitly change that
+
+	bool locReturnValue = false;
+
+	// Sanity check against a NULL output pointer
+	if (!outCMMLRoot) {
+		cout << "outCMMLRoot is NULL" << endl;
+		return false;
+	}
+
+	// Narrow the text given us, so we can pass it to XTag
+	string locCMMLRootText = StringHelper::toNarrowStr(inCMMLRootText);
+
+	// Look for a <cmml> tag
+	XTag *locRootParser = NULL;
+	locRootParser = xtag_new_parse(locCMMLRootText.c_str(), locCMMLRootText.size());
+	if (!locRootParser) {
+		// Couldn't find a tag at all
+		locReturnValue = false;
+		goto cleanup;
+	}
+
+	// Ensure we found a <cmml> tag
+
+	if (strcmp(xtag_get_name(locRootParser), "cmml") != 0) {
+		// This ain't no CMML tag!
+		locReturnValue = false;
+		goto cleanup;
+	}
+
+	XTag *locCMMLParser = locRootParser;
+
+	// Look for a <stream> tag
+	
+	XTag *locStreamParser = NULL;
+	locStreamParser = xtag_first_child(locCMMLParser, "stream");
+	if (locStreamParser) {
+		// We found a stream tag, so go parse it
+		XTAG_PARSE_INTO(locStreamParser, parseStreamTag, C_StreamTag, setStream, outCMMLRoot);
+	}
+
+	// Look for a <head> tag
+	
+	XTag *locHeadParser = NULL;
+	locHeadParser = xtag_first_child(locCMMLParser, "head");
+	if (locHeadParser) {
+		// We found a head tag, so go parse it
+		XTAG_PARSE_INTO(locHeadParser, parseHeadTag, C_HeadTag, setHead, outCMMLRoot);
+	} else {
+		// I have no head!  I am invalid!
+		locReturnValue = false;
+		goto cleanup;
+	}
+
+	// Look for multiple <clip> tags, and shove them into a clip list
+	
+	C_ClipTagList *locClipList = new C_ClipTagList;
+	XTag *locClipParser = NULL;
+	bool locFoundAtLeastOneClip = false;
+	for (	locClipParser = xtag_first_child(locCMMLParser, "clip");
+			locClipParser != NULL;
+			locClipParser = xtag_next_child(locCMMLParser, "clip")) {
+		locFoundAtLeastOneClip = true;
+		XTAG_PARSE_INTO(locClipParser, parseClipTag, C_ClipTag, addTag, locClipList);
+	}
+
+	if (locFoundAtLeastOneClip) {
+		outCMMLRoot->setClipList(locClipList);
+	}
+
+	//delete locClipList;
+
+	// If we got to here, we got a successful parse
+
+	locReturnValue = true;
+
+cleanup:
+
+	if (locRootParser) {
+		//xtag_free(locRootParser);
+	}
+
+	return locReturnValue;
+}
+
+
+bool CMMLParser::parseClipTag(wstring inClipText, C_ClipTag* outClip)
+{
+	// Assume we are unsuccessful unless we explicitly change that
+
+	bool locReturnValue = false;
+
+	// Sanity check against a NULL output pointer
+	if (!outClip) {
+		return false;
+	}
+
+	// Narrow the text given us, so we can pass it to XTag
+	string locClipText = StringHelper::toNarrowStr(inClipText);
+
+	// Look for a <cmml> tag
+	XTag *locClipParser = NULL;
+	locClipParser = xtag_new_parse(locClipText.c_str(), locClipText.size());
+	if (locClipParser) {
+		// Found some sort of tag
+		if (strcmp(xtag_get_name(locClipParser), "clip") == 0) {
+			// Found a <clip> tag, go parse it
+			locReturnValue = parseClipTag(locClipParser, outClip);
+		}
+	}
+
+	//xtag_free(locClipParser);
+
+	return locReturnValue;
+}
+
+
+bool CMMLParser::parseHeadTag(wstring inHeadText, C_HeadTag* outHead)
+{
+	// Assume we are unsuccessful unless we explicitly change that
+
+	bool locReturnValue = false;
+
+	// Sanity check against a NULL output pointer
+	if (!outHead) {
+		return false;
+	}
+
+	// Narrow the text given us, so we can pass it to XTag
+	string locHeadText = StringHelper::toNarrowStr(inHeadText);
+
+	// Set up an XTag parser
+	XTag *locHeadParser = NULL;
+	locHeadParser = xtag_new_parse(locHeadText.c_str(), locHeadText.size());
+	if (locHeadParser) {
+		if (strcmp(xtag_get_name(locHeadParser), "head") == 0) {
+			locReturnValue = parseHeadTag(locHeadParser, outHead);
+		}
+	}
+
+	//xtag_free(locTextParser);
+
+	return locReturnValue;
+}
+
+
+
+bool CMMLParser::parseStreamTag(XTag* inStreamParser, C_StreamTag* outStream)
+{
+	XTAG_SET_ATTRIBUTE(inStreamParser, "id", outStream, setId);
+	XTAG_SET_ATTRIBUTE(inStreamParser, "timebase", outStream, setTimebase);
+	XTAG_SET_ATTRIBUTE(inStreamParser, "utc", outStream, setUtc);
+
+	XTAG_PARSE_LIST(C_ImportTag, "import", parseImportTag,
+		inStreamParser, outStream, importList);
+
+	return true;
+}
+
+
+bool CMMLParser::parseHeadTag(XTag* inHeadParser, C_HeadTag* outHead)
+{
+	XTAG_SET_ATTRIBUTE(inHeadParser, "id", outHead, setId);
+	XTAG_SET_ATTRIBUTE(inHeadParser, "profile", outHead, setProfile);
+
+	XTAG_EXACTLY_ONE_CHILD(inHeadParser, "title");
+	XTAG_PARSE_CHILD(inHeadParser, "title", parseTitleTag, C_TitleTag, setTitle, outHead);
+	XTAG_PARSE_CHILD(inHeadParser, "base", parseBaseTag, C_BaseTag, setBase, outHead);
+
+	XTAG_PARSE_LIST(C_MetaTag, "meta", parseMetaTag, inHeadParser, outHead, metaList);
+
+	// i18n
+	XTAG_SET_ATTRIBUTE(inHeadParser, "lang", outHead, setLang);
+	XTAG_SET_ATTRIBUTE(inHeadParser, "dir", outHead, setDirn);
+
+	return true;
+}
+
+bool CMMLParser::parseTitleTag(XTag* inTitleParser, C_TitleTag* outTitle)
+{
+	XTAG_SET_ATTRIBUTE(inTitleParser, "id", outTitle, setId);
+
+	XTAG_SET_CDATA(inTitleParser, outTitle);
+
+	// i18n
+	XTAG_SET_ATTRIBUTE(inTitleParser, "lang", outTitle, setLang);
+	XTAG_SET_ATTRIBUTE(inTitleParser, "dir", outTitle, setDirn);
+
+	return true;
+}
+
+bool CMMLParser::parseBaseTag(XTag* inBaseParser, C_BaseTag* outBase)
+{
+	XTAG_SET_ATTRIBUTE(inBaseParser, "id", outBase, setId);
+	XTAG_SET_ATTRIBUTE(inBaseParser, "href", outBase, setHref);
+	XTAG_REQUIRED_ATTRIBUTE(inBaseParser, "href", outBase);
+
+	return true;
+}
+
+bool CMMLParser::parseMetaTag(XTag* inMetaParser, C_MetaTag* outMeta)
+{
+	XTAG_SET_ATTRIBUTE(inMetaParser, "scheme", outMeta, setScheme);
+	XTAG_SET_ATTRIBUTE(inMetaParser, "content", outMeta, setContent);
+	XTAG_SET_ATTRIBUTE(inMetaParser, "id", outMeta, setId);
+	XTAG_SET_ATTRIBUTE(inMetaParser, "name", outMeta, setName);
+
+	// i18n
+	XTAG_SET_ATTRIBUTE(inMetaParser, "lang", outMeta, setLang);
+	XTAG_SET_ATTRIBUTE(inMetaParser, "dir", outMeta, setDirn);
+
+	return true;
+}
+
+bool CMMLParser::parseClipTag(XTag* inClipParser, C_ClipTag* outClip)
+{
+	XTAG_SET_ATTRIBUTE(inClipParser, "track", outClip, setTrack);
+	XTAG_SET_ATTRIBUTE(inClipParser, "id", outClip, setId);
+	XTAG_SET_ATTRIBUTE(inClipParser, "start", outClip, setStart);
+	XTAG_REQUIRED_ATTRIBUTE(inClipParser, "start", outClip);
+	XTAG_SET_ATTRIBUTE(inClipParser, "end", outClip, setEnd);
+
+	XTAG_PARSE_LIST(C_MetaTag, "meta", parseMetaTag, inClipParser, outClip, metaList);
+
+	XTAG_PARSE_CHILD(inClipParser, "a", parseAnchorTag, C_AnchorTag, setAnchor, outClip);
+	XTAG_PARSE_CHILD(inClipParser, "img", parseImageTag, C_ImageTag, setImage, outClip);
+	XTAG_PARSE_CHILD(inClipParser, "desc", parseDescTag, C_DescTag, setDesc, outClip);
+
+	// i18n
+	XTAG_SET_ATTRIBUTE(inClipParser, "lang", outClip, setLang);
+	XTAG_SET_ATTRIBUTE(inClipParser, "dir", outClip, setDirn);
+
+	return true;
+}
+
+bool CMMLParser::parseAnchorTag(XTag* inAnchorParser, C_AnchorTag* outAnchor)
+{
+	XTAG_SET_ATTRIBUTE(inAnchorParser, "id", outAnchor, setId);
+	XTAG_SET_ATTRIBUTE(inAnchorParser, "class", outAnchor, setCls);
+	XTAG_SET_ATTRIBUTE(inAnchorParser, "href", outAnchor, setHref);
+	XTAG_REQUIRED_ATTRIBUTE(inAnchorParser, "href", outAnchor);
+
+	XTAG_SET_CDATA(inAnchorParser, outAnchor);
+
+	// i18n
+	XTAG_SET_ATTRIBUTE(inAnchorParser, "lang", outAnchor, setLang);
+	XTAG_SET_ATTRIBUTE(inAnchorParser, "dir", outAnchor, setDirn);
+
+	return true;
+}
+
+bool CMMLParser::parseImageTag(XTag* inImageParser, C_ImageTag* outImage)
+{
+	XTAG_SET_ATTRIBUTE(inImageParser, "id", outImage, setId);
+	XTAG_SET_ATTRIBUTE(inImageParser, "src", outImage, setSrc);
+	XTAG_REQUIRED_ATTRIBUTE(inImageParser, "src", outImage);
+	XTAG_SET_ATTRIBUTE(inImageParser, "alt", outImage, setAlt);
+
+	// i18n
+	XTAG_SET_ATTRIBUTE(inImageParser, "lang", outImage, setLang);
+	XTAG_SET_ATTRIBUTE(inImageParser, "dir", outImage, setDirn);
+
+	return true;
+}
+
+bool CMMLParser::parseDescTag(XTag* inDescParser, C_DescTag* outDesc)
+{
+	XTAG_SET_ATTRIBUTE(inDescParser, "id", outDesc, setId);
+
+	XTAG_SET_CDATA(inDescParser, outDesc);
+
+	// i18n
+	XTAG_SET_ATTRIBUTE(inDescParser, "lang", outDesc, setLang);
+	XTAG_SET_ATTRIBUTE(inDescParser, "dir", outDesc, setDirn);
+
+	return true;
+}
+
+bool CMMLParser::parseImportTag(XTag* inImportParser, C_ImportTag* outImport)
+{
+	XTAG_SET_ATTRIBUTE(inImportParser, "granulerate", outImport, setGranuleRate);
+	XTAG_SET_ATTRIBUTE(inImportParser, "contenttype", outImport, setContentType);
+	XTAG_SET_ATTRIBUTE(inImportParser, "src", outImport, setSrc);
+	XTAG_SET_ATTRIBUTE(inImportParser, "start", outImport, setStart);
+	XTAG_SET_ATTRIBUTE(inImportParser, "end", outImport, setEnd);
+	XTAG_SET_ATTRIBUTE(inImportParser, "title", outImport, setTitle);
+
+	XTAG_PARSE_LIST(C_ParamTag, "param", parseParamTag, inImportParser, outImport, paramList);
+
+	return true;
+}
+
+bool CMMLParser::parseParamTag(XTag* inParamParser, C_ParamTag* outParam)
+{
+	XTAG_SET_ATTRIBUTE(inParamParser, "id", outParam, setId);
+	XTAG_SET_ATTRIBUTE(inParamParser, "name", outParam, setName);
+	XTAG_REQUIRED_ATTRIBUTE(inParamParser, "name", outParam);
+	XTAG_SET_ATTRIBUTE(inParamParser, "value", outParam, setContent);
+	XTAG_REQUIRED_ATTRIBUTE(inParamParser, "value", outParam);
+
+	return true;
+}
+
+#undef XTAG_REQUIRED_ATTRIBUTE
+
+#undef XTAG_SET_ATTRIBUTE
+
+#undef XTAG_PARSE_INTO
+
+#undef XTAG_SET_CDATA


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.cpp
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.h	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.h	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,75 @@
+//===========================================================================
+//Copyright (C) 2004-2005 Zentaro Kavanagh
+//
+//Copyright (C) 2005 Commonwealth Scientific and Industrial Research
+//   Organisation (CSIRO) Australia
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+#pragma once
+
+
+#include <libCMMLTags/libCMMLTags.h>
+#include <libCMMLParse/libCMMLParse.h>
+#include <libCMMLParse/xtag.h>
+
+#include <string>
+
+using namespace std;
+
+
+class LIBCMMLPARSE_API CMMLParser
+{
+public:
+	CMMLParser(void);
+	~CMMLParser(void);
+
+	//C_CMMLTag* genericParseTag(string inCMMLText);
+	//bool parseCMMLDoc(string inCMMLDocText, C_CMMLDoc* outDoc);
+	bool parseClipTag(wstring inClipText, C_ClipTag* outClip);
+	bool parseHeadTag(wstring inHeadText, C_HeadTag* outHead);
+	bool parseCMMLRootTag(wstring inCMMLRootText, C_CMMLRootTag* outCMMLRoot);
+	bool parseDocFromFile(wstring inFilename, C_CMMLDoc* outCMMLDoc);
+
+
+
+protected:
+	bool parseStreamTag(XTag* inStreamParser, C_StreamTag* outStream);
+	bool parseHeadTag(XTag* inHeadParser, C_HeadTag* outHead);
+	bool parseClipTag(XTag* inClipParser, C_ClipTag* outClip);
+	bool parseImportTag(XTag* inImportParser, C_ImportTag* outImport);
+	bool parseBaseTag(XTag* inBaseParser, C_BaseTag* outBase);
+	bool parseTitleTag(XTag* inTitleParser, C_TitleTag* outTitle);
+	bool parseMetaTag(XTag* inMetaParser, C_MetaTag* outMeta);
+	bool parseAnchorTag(XTag* inAnchorParser, C_AnchorTag* outAnchor);
+	bool parseImageTag(XTag* inImageParser, C_ImageTag* outImage);
+	bool parseDescTag(XTag* inDescParser, C_DescTag* outDesc);
+	bool parseParamTag(XTag* inParamParser, C_ParamTag* outParam);
+
+};


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/CMMLParser.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.c
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.c	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.c	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,539 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8. Source code file.
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+    Sept 2001: fixed const & error conditions per
+	mods suggested by S. Parent & A. Lillich.
+    June 2002: Tim Dodd added detection and handling of incomplete
+	source sequences, enhanced error detection, added casts
+	to eliminate compiler warnings.
+    July 2003: slight mods to back out aggressive FFFE detection.
+    Jan 2004: updated switches in from-UTF8 conversions.
+    Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
+
+    See the header file "ConvertUTF.h" for complete documentation.
+
+------------------------------------------------------------------------ */
+
+
+#include "ConvertUTF.h"
+#ifdef CVTUTF_DEBUG
+#include <stdio.h>
+#endif
+
+static const int halfShift  = 10; /* used for shifting by 10 bits */
+
+static const UTF32 halfBase = 0x0010000UL;
+static const UTF32 halfMask = 0x3FFUL;
+
+#define UNI_SUR_HIGH_START  (UTF32)0xD800
+#define UNI_SUR_HIGH_END    (UTF32)0xDBFF
+#define UNI_SUR_LOW_START   (UTF32)0xDC00
+#define UNI_SUR_LOW_END     (UTF32)0xDFFF
+#define false	   0
+#define true	    1
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF16 (
+	const UTF32** sourceStart, const UTF32* sourceEnd, 
+	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF32* source = *sourceStart;
+    UTF16* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch;
+	if (target >= targetEnd) {
+	    result = targetExhausted; break;
+	}
+	ch = *source++;
+	if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+	    /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		if (flags == strictConversion) {
+		    --source; /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		} else {
+		    *target++ = UNI_REPLACEMENT_CHAR;
+		}
+	    } else {
+		*target++ = (UTF16)ch; /* normal case */
+	    }
+	} else if (ch > UNI_MAX_LEGAL_UTF32) {
+	    if (flags == strictConversion) {
+		result = sourceIllegal;
+	    } else {
+		*target++ = UNI_REPLACEMENT_CHAR;
+	    }
+	} else {
+	    /* target is a character in range 0xFFFF - 0x10FFFF. */
+	    if (target + 1 >= targetEnd) {
+		--source; /* Back up source pointer! */
+		result = targetExhausted; break;
+	    }
+	    ch -= halfBase;
+	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+	}
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF32 (
+	const UTF16** sourceStart, const UTF16* sourceEnd, 
+	UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF32* target = *targetStart;
+    UTF32 ch, ch2;
+    while (source < sourceEnd) {
+	const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */
+	ch = *source++;
+	/* If we have a surrogate pair, convert to UTF32 first. */
+	if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+	    /* If the 16 bits following the high surrogate are in the source buffer... */
+	    if (source < sourceEnd) {
+		ch2 = *source;
+		/* If it's a low surrogate, convert to UTF32. */
+		if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+		    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+			+ (ch2 - UNI_SUR_LOW_START) + halfBase;
+		    ++source;
+		} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+		    --source; /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		}
+	    } else { /* We don't have the 16 bits following the high surrogate. */
+		--source; /* return to the high surrogate */
+		result = sourceExhausted;
+		break;
+	    }
+	} else if (flags == strictConversion) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+		--source; /* return to the illegal value itself */
+		result = sourceIllegal;
+		break;
+	    }
+	}
+	if (target >= targetEnd) {
+	    source = oldSource; /* Back up source pointer! */
+	    result = targetExhausted; break;
+	}
+	*target++ = ch;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+#ifdef CVTUTF_DEBUG
+if (result == sourceIllegal) {
+    fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
+    fflush(stderr);
+}
+#endif
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
+ * left as-is for anyone who may want to do such conversion, which was
+ * allowed in earlier algorithms.
+ */
+static const char trailingBytesForUTF8[256] = {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/*
+ * Magic values subtracted from a buffer value during UTF8 conversion.
+ * This table contains as many values as there might be trailing bytes
+ * in a UTF-8 sequence.
+ */
+static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 
+		     0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+
+/*
+ * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
+ * into the first byte, depending on how many bytes follow.  There are
+ * as many entries in this table as there are UTF-8 sequence types.
+ * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
+ * for *legal* UTF-8 will be 4 or fewer bytes total.
+ */
+static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+/* --------------------------------------------------------------------- */
+
+/* The interface converts a whole buffer to avoid function-call overhead.
+ * Constants have been gathered. Loops & conditionals have been removed as
+ * much as possible for efficiency, in favor of drop-through switches.
+ * (See "Note A" at the bottom of the file for equivalent code.)
+ * If your compiler supports it, the "isLegalUTF8" call can be turned
+ * into an inline function.
+ */
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF16toUTF8 (
+	const UTF16** sourceStart, const UTF16* sourceEnd, 
+	UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF16* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch;
+	unsigned short bytesToWrite = 0;
+	const UTF32 byteMask = 0xBF;
+	const UTF32 byteMark = 0x80; 
+	const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
+	ch = *source++;
+	/* If we have a surrogate pair, convert to UTF32 first. */
+	if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
+	    /* If the 16 bits following the high surrogate are in the source buffer... */
+	    if (source < sourceEnd) {
+		UTF32 ch2 = *source;
+		/* If it's a low surrogate, convert to UTF32. */
+		if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
+		    ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+			+ (ch2 - UNI_SUR_LOW_START) + halfBase;
+		    ++source;
+		} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
+		    --source; /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		}
+	    } else { /* We don't have the 16 bits following the high surrogate. */
+		--source; /* return to the high surrogate */
+		result = sourceExhausted;
+		break;
+	    }
+	} else if (flags == strictConversion) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
+		--source; /* return to the illegal value itself */
+		result = sourceIllegal;
+		break;
+	    }
+	}
+	/* Figure out how many bytes the result will require */
+	if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
+	} else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+	} else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+	} else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;
+	} else {			    bytesToWrite = 3;
+					    ch = UNI_REPLACEMENT_CHAR;
+	}
+
+	target += bytesToWrite;
+	if (target > targetEnd) {
+	    source = oldSource; /* Back up source pointer! */
+	    target -= bytesToWrite; result = targetExhausted; break;
+	}
+	switch (bytesToWrite) { /* note: everything falls through. */
+	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
+	}
+	target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * If not calling this from ConvertUTF8to*, then the length can be set by:
+ *  length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns false.  The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+
+static Boolean isLegalUTF8(const UTF8 *source, int length) {
+    UTF8 a;
+    const UTF8 *srcptr = source+length;
+    switch (length) {
+    default: return false;
+	/* Everything else falls through when "true"... */
+    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+    case 2: if ((a = (*--srcptr)) > 0xBF) return false;
+
+	switch (*source) {
+	    /* no fall-through in this inner switch */
+	    case 0xE0: if (a < 0xA0) return false; break;
+	    case 0xED: if (a > 0x9F) return false; break;
+	    case 0xF0: if (a < 0x90) return false; break;
+	    case 0xF4: if (a > 0x8F) return false; break;
+	    default:   if (a < 0x80) return false;
+	}
+
+    case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+    }
+    if (*source > 0xF4) return false;
+    return true;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Exported function to return whether a UTF-8 sequence is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
+    int length = trailingBytesForUTF8[*source]+1;
+    if (source+length > sourceEnd) {
+	return false;
+    }
+    return isLegalUTF8(source, length);
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF16 (
+	const UTF8** sourceStart, const UTF8* sourceEnd, 
+	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF8* source = *sourceStart;
+    UTF16* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch = 0;
+	unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+	if (source + extraBytesToRead >= sourceEnd) {
+	    result = sourceExhausted; break;
+	}
+	/* Do this check whether lenient or strict */
+	if (! isLegalUTF8(source, extraBytesToRead+1)) {
+	    result = sourceIllegal;
+	    break;
+	}
+	/*
+	 * The cases all fall through. See "Note A" below.
+	 */
+	switch (extraBytesToRead) {
+	    case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+	    case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
+	    case 3: ch += *source++; ch <<= 6;
+	    case 2: ch += *source++; ch <<= 6;
+	    case 1: ch += *source++; ch <<= 6;
+	    case 0: ch += *source++;
+	}
+	ch -= offsetsFromUTF8[extraBytesToRead];
+
+	if (target >= targetEnd) {
+	    source -= (extraBytesToRead+1); /* Back up source pointer! */
+	    result = targetExhausted; break;
+	}
+	if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		if (flags == strictConversion) {
+		    source -= (extraBytesToRead+1); /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		} else {
+		    *target++ = UNI_REPLACEMENT_CHAR;
+		}
+	    } else {
+		*target++ = (UTF16)ch; /* normal case */
+	    }
+	} else if (ch > UNI_MAX_UTF16) {
+	    if (flags == strictConversion) {
+		result = sourceIllegal;
+		source -= (extraBytesToRead+1); /* return to the start */
+		break; /* Bail out; shouldn't continue */
+	    } else {
+		*target++ = UNI_REPLACEMENT_CHAR;
+	    }
+	} else {
+	    /* target is a character in range 0xFFFF - 0x10FFFF. */
+	    if (target + 1 >= targetEnd) {
+		source -= (extraBytesToRead+1); /* Back up source pointer! */
+		result = targetExhausted; break;
+	    }
+	    ch -= halfBase;
+	    *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
+	    *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
+	}
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF32toUTF8 (
+	const UTF32** sourceStart, const UTF32* sourceEnd, 
+	UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF32* source = *sourceStart;
+    UTF8* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch;
+	unsigned short bytesToWrite = 0;
+	const UTF32 byteMask = 0xBF;
+	const UTF32 byteMark = 0x80; 
+	ch = *source++;
+	if (flags == strictConversion ) {
+	    /* UTF-16 surrogate values are illegal in UTF-32 */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		--source; /* return to the illegal value itself */
+		result = sourceIllegal;
+		break;
+	    }
+	}
+	/*
+	 * Figure out how many bytes the result will require. Turn any
+	 * illegally large UTF32 things (> Plane 17) into replacement chars.
+	 */
+	if (ch < (UTF32)0x80) {	     bytesToWrite = 1;
+	} else if (ch < (UTF32)0x800) {     bytesToWrite = 2;
+	} else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;
+	} else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;
+	} else {			    bytesToWrite = 3;
+					    ch = UNI_REPLACEMENT_CHAR;
+					    result = sourceIllegal;
+	}
+	
+	target += bytesToWrite;
+	if (target > targetEnd) {
+	    --source; /* Back up source pointer! */
+	    target -= bytesToWrite; result = targetExhausted; break;
+	}
+	switch (bytesToWrite) { /* note: everything falls through. */
+	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
+	    case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+	}
+	target += bytesToWrite;
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* --------------------------------------------------------------------- */
+
+ConversionResult ConvertUTF8toUTF32 (
+	const UTF8** sourceStart, const UTF8* sourceEnd, 
+	UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
+    ConversionResult result = conversionOK;
+    const UTF8* source = *sourceStart;
+    UTF32* target = *targetStart;
+    while (source < sourceEnd) {
+	UTF32 ch = 0;
+	unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
+	if (source + extraBytesToRead >= sourceEnd) {
+	    result = sourceExhausted; break;
+	}
+	/* Do this check whether lenient or strict */
+	if (! isLegalUTF8(source, extraBytesToRead+1)) {
+	    result = sourceIllegal;
+	    break;
+	}
+	/*
+	 * The cases all fall through. See "Note A" below.
+	 */
+	switch (extraBytesToRead) {
+	    case 5: ch += *source++; ch <<= 6;
+	    case 4: ch += *source++; ch <<= 6;
+	    case 3: ch += *source++; ch <<= 6;
+	    case 2: ch += *source++; ch <<= 6;
+	    case 1: ch += *source++; ch <<= 6;
+	    case 0: ch += *source++;
+	}
+	ch -= offsetsFromUTF8[extraBytesToRead];
+
+	if (target >= targetEnd) {
+	    source -= (extraBytesToRead+1); /* Back up the source pointer! */
+	    result = targetExhausted; break;
+	}
+	if (ch <= UNI_MAX_LEGAL_UTF32) {
+	    /*
+	     * UTF-16 surrogate values are illegal in UTF-32, and anything
+	     * over Plane 17 (> 0x10FFFF) is illegal.
+	     */
+	    if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
+		if (flags == strictConversion) {
+		    source -= (extraBytesToRead+1); /* return to the illegal value itself */
+		    result = sourceIllegal;
+		    break;
+		} else {
+		    *target++ = UNI_REPLACEMENT_CHAR;
+		}
+	    } else {
+		*target++ = ch;
+	    }
+	} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
+	    result = sourceIllegal;
+	    *target++ = UNI_REPLACEMENT_CHAR;
+	}
+    }
+    *sourceStart = source;
+    *targetStart = target;
+    return result;
+}
+
+/* ---------------------------------------------------------------------
+
+    Note A.
+    The fall-through switches in UTF-8 reading code save a
+    temp variable, some decrements & conditionals.  The switches
+    are equivalent to the following loop:
+	{
+	    int tmpBytesToRead = extraBytesToRead+1;
+	    do {
+		ch += *source++;
+		--tmpBytesToRead;
+		if (tmpBytesToRead) ch <<= 6;
+	    } while (tmpBytesToRead > 0);
+	}
+    In UTF-8 writing code, the switches on "bytesToWrite" are
+    similarly unrolled loops.
+
+   --------------------------------------------------------------------- */


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.h	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.h	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8.  Header file.
+
+    Several funtions are included here, forming a complete set of
+    conversions between the three formats.  UTF-7 is not included
+    here, but is handled in a separate source file.
+
+    Each of these routines takes pointers to input buffers and output
+    buffers.  The input buffers are const.
+
+    Each routine converts the text between *sourceStart and sourceEnd,
+    putting the result into the buffer between *targetStart and
+    targetEnd. Note: the end pointers are *after* the last item: e.g. 
+    *(sourceEnd - 1) is the last item.
+
+    The return result indicates whether the conversion was successful,
+    and if not, whether the problem was in the source or target buffers.
+    (Only the first encountered problem is indicated.)
+
+    After the conversion, *sourceStart and *targetStart are both
+    updated to point to the end of last text successfully converted in
+    the respective buffers.
+
+    Input parameters:
+	sourceStart - pointer to a pointer to the source buffer.
+		The contents of this are modified on return so that
+		it points at the next thing to be converted.
+	targetStart - similarly, pointer to pointer to the target buffer.
+	sourceEnd, targetEnd - respectively pointers to the ends of the
+		two buffers, for overflow checking only.
+
+    These conversion functions take a ConversionFlags argument. When this
+    flag is set to strict, both irregular sequences and isolated surrogates
+    will cause an error.  When the flag is set to lenient, both irregular
+    sequences and isolated surrogates are converted.
+
+    Whether the flag is strict or lenient, all illegal sequences will cause
+    an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+    or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+    must check for illegal sequences.
+
+    When the flag is set to lenient, characters over 0x10FFFF are converted
+    to the replacement character; otherwise (when the flag is set to strict)
+    they constitute an error.
+
+    Output parameters:
+	The value "sourceIllegal" is returned from some routines if the input
+	sequence is malformed.  When "sourceIllegal" is returned, the source
+	value will point to the illegal value that caused the problem. E.g.,
+	in UTF-8 when a sequence is malformed, it points to the start of the
+	malformed sequence.  
+
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+		 Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+    The following 4 definitions are compiler-specific.
+    The C standard does not guarantee that wchar_t has at least
+    16 bits, so wchar_t is no less portable than unsigned short!
+    All should be unsigned values to avoid sign extension during
+    bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned long	UTF32;	/* at least 32 bits */
+typedef unsigned short	UTF16;	/* at least 16 bits */
+typedef unsigned char	UTF8;	/* typically 8 bits */
+typedef unsigned char	Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+typedef enum {
+	conversionOK, 		/* conversion successful */
+	sourceExhausted,	/* partial character in source, but hit end */
+	targetExhausted,	/* insuff. room in target for conversion */
+	sourceIllegal		/* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+	strictConversion = 0,
+	lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (
+		const UTF8** sourceStart, const UTF8* sourceEnd, 
+		UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF8 (
+		const UTF16** sourceStart, const UTF16* sourceEnd, 
+		UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+		
+ConversionResult ConvertUTF8toUTF32 (
+		const UTF8** sourceStart, const UTF8* sourceEnd, 
+		UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (
+		const UTF32** sourceStart, const UTF32* sourceEnd, 
+		UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+		
+ConversionResult ConvertUTF16toUTF32 (
+		const UTF16** sourceStart, const UTF16* sourceEnd, 
+		UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (
+		const UTF32** sourceStart, const UTF32* sourceEnd, 
+		UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* --------------------------------------------------------------------- */


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ConvertUTF.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ReadMe.txt
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ReadMe.txt	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ReadMe.txt	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,32 @@
+========================================================================
+    DYNAMIC LINK LIBRARY : libCMMLParse Project Overview
+========================================================================
+
+AppWizard has created this libCMMLParse DLL for you.  
+This file contains a summary of what you will find in each of the files that
+make up your libCMMLParse application.
+
+
+libCMMLParse.vcproj
+    This is the main project file for VC++ projects generated using an Application Wizard. 
+    It contains information about the version of Visual C++ that generated the file, and 
+    information about the platforms, configurations, and project features selected with the
+    Application Wizard.
+
+libCMMLParse.cpp
+    This is the main DLL source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named libCMMLParse.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/ReadMe.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.cpp	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.cpp	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,20 @@
+// libCMMLParse.cpp : Defines the entry point for the DLL application.
+//
+
+#include "stdafx.h"
+#include "libCMMLParse.h"
+BOOL APIENTRY DllMain( HANDLE, 
+                       DWORD ul_reason_for_call, 
+                       LPVOID
+					 )
+{
+	switch (ul_reason_for_call)
+	{
+	case DLL_PROCESS_ATTACH:
+	case DLL_THREAD_ATTACH:
+	case DLL_THREAD_DETACH:
+	case DLL_PROCESS_DETACH:
+		break;
+	}
+    return TRUE;
+}


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.cpp
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.h	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.h	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,11 @@
+// The following ifdef block is the standard way of creating macros which make exporting 
+// from a DLL simpler. All files within this DLL are compiled with the LIBCMMLPARSE_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see 
+// LIBCMMLPARSE_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+#ifdef LIBCMMLPARSE_EXPORTS
+#define LIBCMMLPARSE_API __declspec(dllexport)
+#else
+#define LIBCMMLPARSE_API __declspec(dllimport)
+#endif


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.vcproj
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.vcproj	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/libCMMLParse.vcproj	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="libCMMLParse"
+	ProjectGUID="{899EB7AD-26BF-4495-9BE5-EADECCC288B2}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..;..\..\..\helper"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBCMMLPARSE_EXPORTS"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"
+				CallingConvention="2"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/libCMMLParse.dll"
+				LinkIncremental="2"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/libCMMLParse.pdb"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/libCMMLParse.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..;..\..\..\helper"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBCMMLPARSE_EXPORTS"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="2"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"
+				CallingConvention="2"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/libCMMLParse.dll"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				ImportLibrary="$(OutDir)/libCMMLParse.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\CMMLParser.cpp">
+			</File>
+			<File
+				RelativePath=".\ConvertUTF.c">
+			</File>
+			<File
+				RelativePath=".\libCMMLParse.cpp">
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp">
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\xlist.c">
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						CallingConvention="2"/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\xtag.c">
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						CallingConvention="2"/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\CMMLParser.h">
+			</File>
+			<File
+				RelativePath=".\ConvertUTF.h">
+			</File>
+			<File
+				RelativePath=".\libCMMLParse.h">
+			</File>
+			<File
+				RelativePath=".\stdafx.h">
+			</File>
+			<File
+				RelativePath=".\xlist.h">
+			</File>
+			<File
+				RelativePath=".\xtag.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.cpp	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.cpp	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// libCMMLParse.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.cpp
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.h	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.h	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,13 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+
+#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+// TODO: reference additional headers your program requires here


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/stdafx.h
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.c
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.c	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.c	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,251 @@
+//===========================================================================
+//Copyright (C) 2005 Commonwealth Scientific and Industrial Research
+//                   Organisation (CSIRO) Australia
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+#include <stdlib.h>
+
+#include "stdafx.h"
+#include "xlist.h"
+
+static XList *
+xlist_node_new (void * data)
+{
+  XList * l;
+
+  l = (XList *) malloc (sizeof (XList));
+  l->prev = l->next = NULL;
+  l->data = data;
+
+  return l;
+}
+
+XList *
+xlist_new (void)
+{
+  return NULL;
+}
+
+XList *
+xlist_clone (XList * list)
+{
+  XList * l, * new_list;
+
+  if (list == NULL) return NULL;
+  new_list = xlist_new ();
+
+  for (l = list; l; l = l->next) {
+    new_list = xlist_append (new_list, l->data);
+  }
+
+  return new_list;
+}
+
+XList *
+xlist_clone_with (XList * list, XCloneFunc clone)
+{
+  XList * l, * new_list;
+  void * new_data;
+
+  if (list == NULL) return NULL;
+  if (clone == NULL) return xlist_clone (list);
+
+  new_list = xlist_new ();
+
+  for (l = list; l; l = l->next) {
+    new_data = clone (l->data);
+    new_list = xlist_append (new_list, new_data);
+  }
+
+  return new_list;
+}
+
+
+XList *
+xlist_tail (XList * list)
+{
+  XList * l;
+  for (l = list; l; l = l->next)
+    if (l->next == NULL) return l;
+  return NULL;
+}
+
+XList *
+xlist_prepend (XList * list, void * data)
+{
+  XList * l = xlist_node_new (data);
+
+  if (list == NULL) return l;
+
+  l->next = list;
+  list->prev = l;
+
+  return l;
+}
+
+XList *
+xlist_append (XList * list, void * data)
+{
+  XList * l = xlist_node_new (data);
+  XList * last;
+
+  if (list == NULL) return l;
+
+  last = xlist_tail (list);
+  if (last) last->next = l;
+  l->prev = last; 
+  return list;
+}
+
+XList *
+xlist_add_before (XList * list, void * data, XList * node)
+{
+  XList * l, * p;
+
+  if (list == NULL) return xlist_node_new (data);
+  if (node == NULL) return xlist_append (list, data);
+  if (node == list) return xlist_prepend (list, data);
+
+  l = xlist_node_new (data);
+  p = node->prev;
+
+  l->prev = p;
+  l->next = node;
+  if (p) p->next = l;
+  node->prev = l;
+  
+  return list;
+}
+
+XList *
+xlist_add_after (XList * list, void * data, XList * node)
+{
+  XList * l, * n;
+
+  if (node == NULL) return xlist_prepend (list, data);
+
+  l = xlist_node_new (data);
+  n = node->next;
+
+  l->prev = node;
+  l->next = n;
+  if (n) n->prev = l;
+  node->next = l;
+
+  return list;
+}
+
+XList *
+xlist_find (XList * list, void * data)
+{
+  XList * l;
+
+  for (l = list; l; l = l->next)
+    if (l->data == data) return l;
+
+  return NULL;
+}
+
+XList *
+xlist_remove (XList * list, XList * node)
+{
+  if (node == NULL) return list;
+
+  if (node->prev) node->prev->next = node->next;
+  if (node->next) node->next->prev = node->prev;
+
+  if (node == list) return list->next;
+  else return list;
+}
+
+int
+xlist_length (XList * list)
+{
+  XList * l;
+  int c = 0;
+
+  for (l = list; l; l = l->next)
+    c++;
+
+  return c;
+}
+
+int
+xlist_is_empty (XList * list)
+{
+  return (list == NULL);
+}
+
+int
+xlist_is_singleton (XList * list)
+{
+  if (list == NULL) return 0;
+  if (list->next == NULL) return 1;
+  else return 0;
+}
+
+/*
+ * xlist_free_with (list, free_func)
+ *
+ * Step through list 'list', freeing each node using free_func(), and
+ * also free the list structure itself.
+ */
+XList *
+xlist_free_with (XList * list, XFreeFunc free_func)
+{
+  XList * l, * ln;
+
+  for (l = list; l; l = ln) {
+    ln = l->next;
+    free_func (l->data);
+    free (l);
+  }
+
+  return NULL;
+}
+
+/*
+ * xlist_free (list)
+ *
+ * Free the list structure 'list', but not its nodes.
+ */
+XList *
+xlist_free (XList * list)
+{
+  XList * l, * ln;
+
+  for (l = list; l; l = ln) {
+    ln = l->next;
+    free (l);
+  }
+
+  return NULL;
+}
+

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.h	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xlist.h	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,181 @@
+//===========================================================================
+//Copyright (C) 2005 Commonwealth Scientific and Industrial Research
+//                   Organisation (CSIRO) Australia
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+
+#ifndef __XLIST__
+#define __XLIST__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * A doubly linked list
+ */
+typedef struct _XList XList;
+
+struct _XList {
+  XList * prev;
+  XList * next;
+  void * data;
+};
+
+/**
+ * Signature of a cloning function.
+ */
+typedef void * (*XCloneFunc) (void * data);
+
+/**
+ * Signature of a freeing function.
+ */
+typedef void * (*XFreeFunc) (void * data);
+
+/** Create a new list
+ * \return a new list
+ */
+XList * xlist_new (void);
+
+/**
+ * Clone a list using the default clone function
+ * \param list the list to clone
+ * \returns a newly cloned list
+ */
+XList * xlist_clone (XList * list);
+
+/**
+ * Clone a list using a custom clone function
+ * \param list the list to clone
+ * \param clone the function to use to clone a list item
+ * \returns a newly cloned list
+ */
+XList * xlist_clone_with (XList * list, XCloneFunc clone);
+
+/**
+ * Return the tail element of a list
+ * \param list the list
+ * \returns the tail element
+ */
+XList * xlist_tail (XList * list);
+
+/**
+ * Prepend a new node to a list containing given data
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \returns the new list head
+ */
+XList * xlist_prepend (XList * list, void * data);
+
+/**
+ * Append a new node to a list containing given data
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \returns the head of the list
+ */
+XList * xlist_append (XList * list, void * data);
+
+/**
+ * Add a new node containing given data before a given node
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \param node the node before which to add the newly created node
+ * \returns the head of the list (which may have changed)
+ */
+XList * xlist_add_before (XList * list, void * data, XList * node);
+
+/**
+ * Add a new node containing given data after a given node
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \param node the node after which to add the newly created node
+ * \returns the head of the list
+ */
+XList * xlist_add_after (XList * list, void * data, XList * node);
+
+/**
+ * Find the first node containing given data in a list
+ * \param list the list
+ * \param data the data element to find
+ * \returns the first node containing given data, or NULL if it is not found
+ */
+XList * xlist_find (XList * list, void * data);
+
+/**
+ * Remove a node from a list
+ * \param list the list
+ * \param node the node to remove
+ * \returns the head of the list (which may have changed)
+ */
+XList * xlist_remove (XList * list, XList * node);
+
+/**
+ * Query the number of items in a list
+ * \param list the list
+ * \returns the number of nodes in the list
+ */
+int xlist_length (XList * list);
+
+/**
+ * Query if a list is empty, ie. contains no items
+ * \param list the list
+ * \returns 1 if the list is empty, 0 otherwise
+ */
+int xlist_is_empty (XList * list);
+
+/**
+ * Query if the list is singleton, ie. contains exactly one item
+ * \param list the list
+ * \returns 1 if the list is singleton, 0 otherwise
+ */
+int xlist_is_singleton (XList * list);
+
+/**
+ * Free a list, using a given function to free each data element
+ * \param list the list
+ * \param free_func a function to free each data element
+ * \returns NULL on success
+ */
+XList * xlist_free_with (XList * list, XFreeFunc free_func);
+
+/**
+ * Free a list, using anx_free() to free each data element
+ * \param list the list
+ * \returns NULL on success
+ */
+XList * xlist_free (XList * list);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __XLIST__ */
+
+

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.c
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.c	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.c	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,701 @@
+//===========================================================================
+//Copyright (C) 2005 Commonwealth Scientific and Industrial Research
+//                   Organisation (CSIRO) Australia
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+
+#include "stdafx.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "xlist.h"
+
+#undef XTAG_DEBUG
+
+#undef FALSE
+#undef TRUE
+
+#define FALSE (0)
+#define TRUE (!FALSE)
+
+#undef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#undef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+typedef struct _XTag XTag;
+typedef struct _XAttribute XAttribute;
+typedef struct _XTagParser XTagParser;
+
+#define XTAG_INTERNAL
+#include "xtag.h"
+
+/*
+ * struct _XTag is kind of a union ... it normally represents a whole
+ * tag (and its children), but it could alternatively represent some
+ * PCDATA. Basically, if tag->pcdata is non-NULL, interpret only it and
+ * ignore the name, attributes and inner_tags.
+ */
+struct _XTag {
+  char * name;
+  char * pcdata;
+  XTag * parent;
+  XList * attributes;
+  XList * children;
+  XList * current_child;
+};
+
+struct _XAttribute {
+  char * name;
+  char * value;
+};
+
+struct _XTagParser {
+  int valid; /* boolean */
+  XTag * current_tag;
+  char * start;
+  char * end;
+};
+
+/* Character classes */
+#define X_NONE           0
+#define X_WHITESPACE  1<<0
+#define X_OPENTAG     1<<1
+#define X_CLOSETAG    1<<2
+#define X_DQUOTE      1<<3
+#define X_SQUOTE      1<<4
+#define X_EQUAL       1<<5
+#define X_SLASH       1<<6
+
+static int
+xtag_cin (char c, int char_class)
+{
+  if (char_class & X_WHITESPACE)
+    if (isspace(c)) return TRUE;
+
+  if (char_class & X_OPENTAG)
+    if (c == '<') return TRUE;
+
+  if (char_class & X_CLOSETAG)
+    if (c == '>') return TRUE;
+
+  if (char_class & X_DQUOTE)
+    if (c == '"') return TRUE;
+
+  if (char_class & X_SQUOTE)
+    if (c == '\'') return TRUE;
+
+  if (char_class & X_EQUAL)
+    if (c == '=') return TRUE;
+
+  if (char_class & X_SLASH)
+    if (c == '/') return TRUE;
+
+  return FALSE;
+}
+
+static int
+xtag_index (XTagParser * parser, int char_class)
+{
+  char * s;
+  int i;
+
+  s = parser->start;
+
+  for (i = 0; s[i] && s != parser->end; i++) {
+    if (xtag_cin(s[i], char_class)) return i;
+  }
+
+  return -1;
+}
+
+static void
+xtag_skip_over (XTagParser * parser, int char_class)
+{
+  char * s;
+  int i;
+
+  if (!parser->valid) return;
+
+  s = (char *)parser->start;
+
+  for (i = 0; s[i] && s != parser->end; i++) {
+    if (!xtag_cin(s[i], char_class)) {
+      parser->start = &s[i];
+      return;
+    }
+  }
+
+  return;
+}
+
+static void
+xtag_skip_whitespace (XTagParser * parser)
+{
+  xtag_skip_over (parser, X_WHITESPACE);
+}
+
+#if 0
+static void
+xtag_skip_to (XTagParser * parser, int char_class)
+{
+  char * s;
+  int i;
+
+  if (!parser->valid) return;
+
+  s = (char *)parser->start;
+
+  for (i = 0; s[i] && s != parser->end; i++) {
+    if (xtag_cin(s[i], char_class)) {
+      parser->start = &s[i];
+      return;
+    }
+  }
+
+  return;  
+}
+#endif
+
+static char *
+xtag_slurp_to (XTagParser * parser, int good_end, int bad_end)
+{
+  char * s, * ret;
+  int xi;
+
+  if (!parser->valid) return NULL;
+
+  s = parser->start;
+
+  xi = xtag_index (parser, good_end | bad_end);
+
+  if (xi > 0 && xtag_cin (s[xi], good_end)) {
+    ret = malloc ((xi+1) * sizeof(char));
+    strncpy (ret, s, xi);
+    ret[xi] = '\0';
+    parser->start = &s[xi];
+    return ret;
+  }
+
+  return NULL;
+}
+
+static int
+xtag_assert_and_pass (XTagParser * parser, int char_class)
+{
+  char * s;
+
+  if (!parser->valid) return FALSE;
+
+  s = parser->start;
+
+  if (!xtag_cin (s[0], char_class)) {
+    parser->valid = FALSE;
+    return FALSE;
+  }
+
+  parser->start = &s[1];
+
+  return TRUE;
+}
+
+static char *
+xtag_slurp_quoted (XTagParser * parser)
+{
+  char * s, * ret;
+  int quote = X_DQUOTE; /* quote char to match on */
+  int xi;
+
+  if (!parser->valid) return NULL;
+
+  xtag_skip_whitespace (parser);
+
+  s = parser->start;
+
+  if (xtag_cin (s[0], X_SQUOTE)) quote = X_SQUOTE;
+
+  if (!xtag_assert_and_pass (parser, quote)) return NULL;
+
+  s = parser->start;
+
+  for (xi = 0; s[xi]; xi++) {
+    if (xtag_cin (s[xi], quote)) {
+      if (!(xi > 1 && s[xi-1] == '\\')) break;
+    }
+  }
+
+  ret = malloc ((xi+1) * sizeof(char));
+  strncpy (ret, s, xi);
+  ret[xi] = '\0';
+  parser->start = &s[xi];
+
+  if (!xtag_assert_and_pass (parser, quote)) return NULL;
+
+  return ret;
+}
+
+static XAttribute *
+xtag_parse_attribute (XTagParser * parser)
+{
+  XAttribute * attr;
+  char * name, * value;
+  char * s;
+
+  if (!parser->valid) return NULL;
+
+  xtag_skip_whitespace (parser);
+ 
+  name = xtag_slurp_to (parser, X_WHITESPACE | X_EQUAL, X_SLASH | X_CLOSETAG);
+
+  if (name == NULL) return NULL;
+
+  xtag_skip_whitespace (parser);
+  s = parser->start;
+
+  if (!xtag_assert_and_pass (parser, X_EQUAL)) {
+#ifdef XTAG_DEBUG
+    printf ("xtag: attr failed EQUAL on <%s>\n", name);
+#endif
+    goto err_free_name;
+  }
+
+  xtag_skip_whitespace (parser);
+
+  value = xtag_slurp_quoted (parser);
+
+  if (value == NULL) {
+#ifdef XTAG_DEBUG
+    printf ("Got NULL quoted attribute value\n");
+#endif
+    goto err_free_name;
+  }
+
+  attr = malloc (sizeof (*attr));
+  attr->name = name;
+  attr->value = value;
+
+  return attr;
+
+ err_free_name:
+  free (name);
+
+  parser->valid = FALSE;
+
+  return NULL;
+}
+
+static XTag *
+xtag_parse_tag (XTagParser * parser)
+{
+  XTag * tag, * inner;
+  XAttribute * attr;
+  char * name;
+  char * pcdata;
+  char * s;
+
+  if (!parser->valid) return NULL;
+
+  if ((pcdata = xtag_slurp_to (parser, X_OPENTAG, X_NONE)) != NULL) {
+    tag = malloc (sizeof (*tag));
+    tag->name = NULL;
+    tag->pcdata = pcdata;
+    tag->parent = parser->current_tag;
+    tag->attributes = NULL;
+    tag->children = NULL;
+    tag->current_child = NULL;
+
+    return tag;
+  }
+
+  s = parser->start;
+
+  /* if this starts a close tag, return NULL and let the parent take it */
+  if (xtag_cin (s[0], X_OPENTAG) && xtag_cin (s[1], X_SLASH))
+    return NULL;
+
+  if (!xtag_assert_and_pass (parser, X_OPENTAG)) return NULL;
+
+  name = xtag_slurp_to (parser, X_WHITESPACE | X_SLASH | X_CLOSETAG, X_NONE);
+
+  if (name == NULL) return NULL;
+
+#ifdef XTAG_DEBUG
+  printf ("<%s ...\n", name);
+#endif
+
+  tag = malloc (sizeof (*tag));
+  tag->name = name;
+  tag->pcdata = NULL;
+  tag->parent = parser->current_tag;
+  tag->attributes = NULL;
+  tag->children = NULL;
+  tag->current_child = NULL;
+
+  s = parser->start;
+
+  if (xtag_cin (s[0], X_WHITESPACE)) {
+    while ((attr = xtag_parse_attribute (parser)) != NULL) {
+      tag->attributes = xlist_append (tag->attributes, attr);
+    }
+  }
+
+  xtag_skip_whitespace (parser);
+
+  s = parser->start;
+
+  if (xtag_cin (s[0], X_CLOSETAG)) {
+    parser->current_tag = tag;
+
+    xtag_assert_and_pass (parser, X_CLOSETAG);
+
+    while ((inner = xtag_parse_tag (parser)) != NULL) {
+      tag->children = xlist_append (tag->children, inner);
+    }
+
+    xtag_skip_whitespace (parser);
+
+    xtag_assert_and_pass (parser, X_OPENTAG);
+    xtag_assert_and_pass (parser, X_SLASH);
+    name = xtag_slurp_to (parser, X_WHITESPACE | X_CLOSETAG, X_NONE);
+    if (name) {
+      if (name && tag->name && strcmp (name, tag->name)) {
+#ifdef XTAG_DEBUG
+        printf ("got %s expected %s\n", name, tag->name);
+#endif
+        parser->valid = FALSE;
+      }
+      free (name);
+    }
+
+    xtag_skip_whitespace (parser);
+    xtag_assert_and_pass (parser, X_CLOSETAG);
+
+  } else {
+    xtag_assert_and_pass (parser, X_SLASH);
+    xtag_assert_and_pass (parser, X_CLOSETAG);
+  }
+
+
+  return tag;
+}
+
+XTag *
+xtag_free (XTag * xtag)
+{
+  XList * l;
+  XAttribute * attr;
+  XTag * child;
+
+  if (xtag == NULL) return NULL;
+
+  if (xtag->name) free (xtag->name);
+  if (xtag->pcdata) free (xtag->pcdata);
+
+  for (l = xtag->attributes; l; l = l->next) {
+    if ((attr = (XAttribute *)l->data) != NULL) {
+      if (attr->name) free (attr->name);
+      if (attr->value) free (attr->value);
+      free (attr);
+    }
+  }
+  xlist_free (xtag->attributes);
+
+  for (l = xtag->children; l; l = l->next) {
+    child = (XTag *)l->data;
+    xtag_free (child);
+  }
+  xlist_free (xtag->children);
+
+  free (xtag);
+
+  return NULL;
+}
+
+XTag *
+xtag_new_parse (const char * s, int n)
+{
+  XTagParser parser;
+  XTag * tag, * ttag, * wrapper;
+
+  parser.valid = TRUE;
+  parser.current_tag = NULL;
+  parser.start = (char *)s;
+
+  if (n == -1)
+    parser.end = NULL;
+  else if (n == 0)
+    return NULL;
+  else
+    parser.end = (char *)&s[n];
+
+  tag = xtag_parse_tag (&parser);
+
+  if (!parser.valid) {
+    xtag_free (tag);
+    return NULL;
+  }
+
+  if ((ttag = xtag_parse_tag (&parser)) != NULL) {
+
+    if (!parser.valid) {
+      xtag_free (ttag);
+      return tag;
+    }
+
+    wrapper = malloc (sizeof (XTag));
+    wrapper->name = NULL;
+    wrapper->pcdata = NULL;
+    wrapper->parent = NULL;
+    wrapper->attributes = NULL;
+    wrapper->children = NULL;
+    wrapper->current_child = NULL;
+
+    wrapper->children = xlist_append (wrapper->children, tag);
+    wrapper->children = xlist_append (wrapper->children, ttag);
+
+    while ((ttag = xtag_parse_tag (&parser)) != NULL) {
+
+      if (!parser.valid) {
+        xtag_free (ttag);
+        return wrapper;
+      }
+
+      wrapper->children = xlist_append (wrapper->children, ttag);
+    }
+    return wrapper;
+  }
+
+  return tag;
+}
+
+char *
+xtag_get_name (XTag * xtag)
+{
+  return xtag ? xtag->name : NULL;
+}
+
+char *
+xtag_get_pcdata (XTag * xtag)
+{
+  XList * l;
+  XTag * child;
+
+  if (xtag == NULL) return NULL;
+
+  for (l = xtag->children; l; l = l->next) {
+    child = (XTag *)l->data;
+    if (child->pcdata != NULL) {
+      return child->pcdata;
+    }
+  }
+
+  return NULL;
+}
+
+char *
+xtag_get_attribute (XTag * xtag, char * attribute)
+{
+  XList * l;
+  XAttribute * attr;
+
+  if (xtag == NULL) return NULL;
+
+  for (l = xtag->attributes; l; l = l->next) {
+    if ((attr = (XAttribute *)l->data) != NULL) {
+      if (attr->name && attribute && !strcmp (attr->name, attribute))
+        return attr->value;
+    }
+  }
+
+  return NULL;
+}
+
+XTag *
+xtag_first_child (XTag * xtag, char * name)
+{
+  XList * l;
+  XTag * child;
+
+  if (xtag == NULL) return NULL;
+
+  if ((l = xtag->children) == NULL) return NULL;
+
+  if (name == NULL) {
+    xtag->current_child = l;
+    return (XTag *)l->data;
+  }
+
+  for (; l; l = l->next) {
+    child = (XTag *)l->data;
+
+    if (child->name && name && !strcmp(child->name, name)) {
+      xtag->current_child = l;
+      return child;
+    }
+  }
+
+  xtag->current_child = NULL;
+
+  return NULL;
+}
+
+XTag *
+xtag_next_child (XTag * xtag, char * name)
+{
+  XList * l;
+  XTag * child;
+
+  if (xtag == NULL) return NULL;
+
+  if ((l = xtag->current_child) == NULL)
+    return xtag_first_child (xtag, name);
+
+  if ((l = l->next) == NULL)
+    return NULL;
+
+  if (name == NULL) {
+    xtag->current_child = l;
+    return (XTag *)l->data;
+  }
+
+  for (; l; l = l->next) {
+    child = (XTag *)l->data;
+
+    if (child->name && name && !strcmp(child->name, name)) {
+      xtag->current_child = l;
+      return child;
+    }
+  }
+
+  xtag->current_child = NULL;
+
+  return NULL;
+}
+
+/*
+ * This snprints function takes a variable list of char *, the last of
+ * which must be NULL, and prints each in turn to buf.
+ * Returns C99-style total length that would have been written, even if
+ * this is larger than n.
+ */
+static int
+xtag_snprints (char * buf, int n, ...)
+{
+  va_list ap;
+  char * s;
+  int len, to_copy, total = 0;
+
+  va_start (ap, n);
+  
+  for (s = va_arg (ap, char *); s; s = va_arg (ap, char *)) {
+    len = (int) strlen (s);
+
+    if ((to_copy = MIN (n, len)) > 0) {
+      memcpy (buf, s, to_copy);
+      buf += to_copy;
+      n -= to_copy;
+    }
+
+    total += len;
+  }
+
+  va_end (ap);
+
+  return total;
+}
+
+int
+xtag_snprint (char * buf, int n, XTag * xtag)
+{
+  int nn, written = 0;
+  XList * l;
+  XAttribute * attr;
+  XTag * child;
+
+#define FORWARD(N) \
+  buf += MIN (n, N); \
+  n = MAX (n-N, 0);  \
+  written += N;
+
+  if (xtag == NULL) {
+    if (n > 0) buf[0] = '\0';
+    return 0;
+  }
+
+  if (xtag->pcdata) {
+    nn = xtag_snprints (buf, n, xtag->pcdata, NULL);
+    FORWARD(nn);
+
+    return written;
+  }
+
+  if (xtag->name) {
+    nn = xtag_snprints (buf, n, "<", xtag->name, NULL);
+    FORWARD(nn);
+
+    for (l = xtag->attributes; l; l = l->next) {
+      attr = (XAttribute *)l->data;
+      
+      nn = xtag_snprints (buf, n, " ", attr->name, "=\"", attr->value, "\"",
+                          NULL);
+      FORWARD(nn);
+    }
+    
+    if (xtag->children == NULL) {
+      nn = xtag_snprints (buf, n, "/>", NULL);
+      FORWARD(nn);
+
+      return written;
+    }
+    
+    nn = xtag_snprints (buf, n, ">", NULL);
+    FORWARD(nn);
+  }
+
+  for (l = xtag->children; l; l = l->next) {
+    child = (XTag *)l->data;
+
+    nn = xtag_snprint (buf, n, child);
+    FORWARD(nn);
+  }
+
+  if (xtag->name) {
+    nn = xtag_snprints (buf, n, "</", xtag->name, ">", NULL);
+    FORWARD(nn);
+  }
+
+  return written;
+}
+


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.h	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.h	2005-01-08 20:07:55 UTC (rev 8691)
@@ -0,0 +1,65 @@
+//===========================================================================
+//Copyright (C) 2005 Commonwealth Scientific and Industrial Research
+//                   Organisation (CSIRO) Australia
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+
+
+#ifndef __XTAG_H__
+#define __XTAG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef XTAG_INTERNAL
+typedef void XTag;
+#endif /* XTAG_INTERNAL */
+
+XTag * xtag_new_parse (const char * s, int n);
+
+char * xtag_get_name (XTag * xtag);
+
+char * xtag_get_pcdata (XTag * xtag);
+
+char * xtag_get_attribute (XTag * xtag, char * attribute);
+
+XTag * xtag_first_child (XTag * xtag, char * name);
+
+XTag * xtag_next_child (XTag * xtag, char * name);
+
+XTag * xtag_free (XTag * xtag);
+
+int xtag_snprint (char * buf, int n, XTag * xtag);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __XTAG_H__ */


Property changes on: trunk/oggdsf/src/lib/codecs/cmml/libCMMLParse/xtag.h
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/oggdsf/src/tests/testCMMLParser/testCMMLParser.cpp
===================================================================
--- trunk/oggdsf/src/tests/testCMMLParser/testCMMLParser.cpp	2005-01-08 19:50:45 UTC (rev 8690)
+++ trunk/oggdsf/src/tests/testCMMLParser/testCMMLParser.cpp	2005-01-08 20:07:55 UTC (rev 8691)
@@ -5,8 +5,13 @@
 
 #include "libCMMLTags/libCMMLTags.h"
 
+#if 1
 #include <libCMMLParse/libCMMLParse.h>
 #include <libCMMLParse/CMMLParser.h>
+#else
+#include <libWinCMMLParse/libWinCMMLParse.h>
+#include <libWinCMMLParse/CMMLParser.h>
+#endif
 
 
 static int headTestNumber = 0;
@@ -22,17 +27,22 @@
 
 	headTestNumber++;
 
-	if (locWasOK == inShouldPass) {
-		// Either we correctly failed, or correctly passed
+	if (locWasOK && inShouldPass) {
+		// We correctly passed: print it out for verification
+		cout << "+++ Correctly passed:" << " " << headTestNumber << endl;
+		wcout << L"Original: " << endl << inHeadString << endl;
+		wcout << L"Parsed output:" << endl << locHead.toString() << endl << endl;
+	} else if (!locWasOK && !inShouldPass) {
+		// We correctly failed
 	} else if (locWasOK) {
 		// We incorrectly passed
-		wcout << "*** INCORRECTLY PASSED (Head) ***" << " " << headTestNumber << endl;
-		wcout << "Original: " << endl << inHeadString << endl;
-		wcout << "Parsed output:" << endl << locHead.toString() << endl << endl;
+		cout << "*** INCORRECTLY PASSED (Head) ***" << " " << headTestNumber << endl;
+		wcout << L"Original: " << endl << inHeadString << endl;
+		wcout << L"Parsed output:" << endl << locHead.toString() << endl << endl;
 	} else {
 		// We incorrectly failed
-		wcout << "*** INCORRECTLY FAILED (Head) ***" << " " << headTestNumber << endl;
-		wcout << "Original: " << endl << inHeadString << endl << endl;
+		cout << "*** INCORRECTLY FAILED (Head) ***" << " " << headTestNumber << endl;
+		wcout << L"Original: " << endl << inHeadString << endl << endl;
 	}
 }
 
@@ -44,17 +54,22 @@
 
 	clipTestNumber++;
 
-	if (locWasOK == inShouldPass) {
-		// Either we correctly failed, or correctly passed
+	if (locWasOK && inShouldPass) {
+		// We correctly passed: print it out for verification
+		cout << "+++ Correctly passed:" << " " << clipTestNumber << endl;
+		wcout << L"Original: " << endl << inClipString << endl;
+		wcout << L"Parsed output:" << endl << locClip.toString() << endl << endl;
+	} else if (!locWasOK && !inShouldPass) {
+		// We correctly failed
 	} else if (locWasOK) {
 		// We incorrectly passed
-		wcout << "*** INCORRECTLY PASSED (Clip) ***" << " " << clipTestNumber << endl;
-		wcout << "Original: " << endl << inClipString << endl;
-		wcout << "Parsed output:" << endl << locClip.toString() << endl << endl;
+		cout << "*** INCORRECTLY PASSED (Clip) ***" << " " << clipTestNumber << endl;
+		wcout << L"Original: " << endl << inClipString << endl;
+		wcout << L"Parsed output:" << endl << locClip.toString() << endl << endl;
 	} else {
 		// We incorrectly failed
-		wcout << "*** INCORRECTLY FAILED (Clip) ***" << " " << clipTestNumber << endl;
-		wcout << "Original: " << endl << inClipString << endl << endl;
+		cout << "*** INCORRECTLY FAILED (Clip) ***" << " " << clipTestNumber << endl;
+		wcout << L"Original: " << endl << inClipString << endl << endl;
 	}
 
 	return locWasOK;
@@ -68,17 +83,22 @@
 
 	rootTestNumber++;
 
-	if (locWasOK == inShouldPass) {
-		// Either we correctly failed, or correctly passed
+	if (locWasOK && inShouldPass) {
+		// We correctly passed: print it out for verification
+		cout << "+++ Correctly passed:" << " " << rootTestNumber << endl;
+		wcout << L"Original: " << endl << inCMMLRootString << endl;
+		wcout << L"Parsed output:" << endl << locCMMLRoot.toString() << endl << endl;
+	} else if (!locWasOK && !inShouldPass) {
+		// We correctly failed
 	} else if (locWasOK) {
 		// We incorrectly passed
-		wcout << "*** INCORRECTLY PASSED (Root) ***" << " " << rootTestNumber << endl;
-		wcout << "Original: " << endl << inCMMLRootString << endl;
-		wcout << "Parsed output:" << endl << locCMMLRoot.toString() << endl << endl;
+		cout << "*** INCORRECTLY PASSED (Root) ***" << " " << rootTestNumber << endl;
+		wcout << L"Original: " << endl << inCMMLRootString << endl;
+		wcout << L"Parsed output:" << endl << locCMMLRoot.toString() << endl << endl;
 	} else {
 		// We incorrectly failed
-		wcout << "*** INCORRECTLY FAILED (Root) ***" << " " << rootTestNumber << endl;
-		wcout << "Original: " << endl << inCMMLRootString << endl << endl;
+		cout << "*** INCORRECTLY FAILED (Root) ***" << " " << rootTestNumber << endl;
+		wcout << L"Original: " << endl << inCMMLRootString << endl << endl;
 	}
 
 	return locWasOK;



More information about the commits mailing list