cmCableData.cxx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2000 National Library of Medicine
  8. All rights reserved.
  9. See COPYRIGHT.txt for copyright details.
  10. =========================================================================*/
  11. #include "cmCableData.h"
  12. #include "cmCacheManager.h"
  13. #include "cmCablePackageCommand.h"
  14. /**
  15. * The cmCableData instance is owned by one cmCableCommand, which is given
  16. * to this constructor.
  17. */
  18. cmCableData::cmCableData(const cmCableCommand* owner,
  19. const std::string& configurationFile):
  20. m_Owner(owner),
  21. m_OutputFileName(configurationFile),
  22. m_OutputFile(configurationFile.c_str()),
  23. m_Indentation(0),
  24. m_Package(NULL),
  25. m_PackageNamespaceDepth(0)
  26. {
  27. this->InitializeOutputFile();
  28. }
  29. /**
  30. * Free all data that was stored here. Also close the output file.
  31. */
  32. cmCableData::~cmCableData()
  33. {
  34. // End last package, if any.
  35. this->EndPackage();
  36. // Finish up the output file.
  37. this->CloseOutputFile();
  38. }
  39. /**
  40. * Write the configuration header to the output file.
  41. */
  42. void cmCableData::InitializeOutputFile()
  43. {
  44. if(m_OutputFile)
  45. {
  46. this->WriteConfigurationHeader();
  47. }
  48. else
  49. {
  50. cmSystemTools::Error("Unable to open CABLE config file: ",
  51. m_OutputFileName.c_str());
  52. }
  53. }
  54. /**
  55. * Close the configuration output file. This writes the configuration
  56. * footer.
  57. */
  58. void cmCableData::CloseOutputFile()
  59. {
  60. if(m_OutputFile)
  61. {
  62. this->WriteConfigurationFooter();
  63. m_OutputFile.close();
  64. }
  65. }
  66. /**
  67. * Write a CABLE configuration file header.
  68. */
  69. void cmCableData::WriteConfigurationHeader()
  70. {
  71. m_OutputFile << m_Indentation << "<?xml version=\"1.0\"?>" << std::endl
  72. << m_Indentation << "<CableConfiguration>" << std::endl;
  73. this->Indent();
  74. }
  75. /**
  76. * Write a CABLE configuration file footer.
  77. */
  78. void cmCableData::WriteConfigurationFooter()
  79. {
  80. this->Unindent();
  81. m_OutputFile << m_Indentation << "</CableConfiguration>" << std::endl;
  82. }
  83. /**
  84. * Print indentation spaces.
  85. */
  86. void
  87. cmCableData::Indentation
  88. ::Print(std::ostream& os) const
  89. {
  90. if(m_Indent <= 0)
  91. { return; }
  92. // Use blocks of 8 spaces to speed up big indents.
  93. unsigned int blockCount = m_Indent >> 3;
  94. unsigned int singleCount = m_Indent & 7;
  95. while(blockCount-- > 0)
  96. {
  97. os << " ";
  98. }
  99. while(singleCount-- > 0)
  100. {
  101. os << " ";
  102. }
  103. }
  104. /**
  105. * Open a namespace with the given name.
  106. */
  107. void cmCableData::OpenNamespace(const std::string& name)
  108. {
  109. m_NamespaceStack.push_back(name);
  110. }
  111. /**
  112. * Close the current namespace, checking whether it has the given name.
  113. */
  114. void cmCableData::CloseNamespace(const std::string& name)
  115. {
  116. if(m_NamespaceStack.empty())
  117. {
  118. cmSystemTools::Error("Unbalanced close-namespace = ", name.c_str());
  119. return;
  120. }
  121. if(m_NamespaceStack.back() != name)
  122. {
  123. cmSystemTools::Error("Wrong name on close-namespace = ", name.c_str());
  124. }
  125. // If this closes the namespace where the current package was opened,
  126. // the package must end as well.
  127. if(m_Package && (m_PackageNamespaceDepth == m_NamespaceStack.size()))
  128. {
  129. this->EndPackage();
  130. }
  131. m_NamespaceStack.pop_back();
  132. }
  133. /**
  134. * Begin a new package definition. If there is a current one, it
  135. * will be ended.
  136. */
  137. void cmCableData::BeginPackage(cmCablePackageCommand* command)
  138. {
  139. // Close the current package, if any.
  140. this->EndPackage();
  141. // Open this package.
  142. m_Package = command;
  143. // Write out the package's header.
  144. m_Package->WritePackageHeader();
  145. // Save the package's opening namespace depth for later verification
  146. // on the end of the package.
  147. m_PackageNamespaceDepth = m_NamespaceStack.size();
  148. }
  149. /**
  150. * End a package definition.
  151. */
  152. void cmCableData::EndPackage()
  153. {
  154. // Make sure we have an open package.
  155. if(!m_Package)
  156. {
  157. return;
  158. }
  159. // Make sure the namespace nesting depth matches the opening depth
  160. // of the package.
  161. if(m_PackageNamespaceDepth != m_NamespaceStack.size())
  162. {
  163. cmSystemTools::Error("Package ended at different namespace depth than"
  164. "it was created!", "");
  165. }
  166. // Write out the package's footer.
  167. m_Package->WritePackageFooter();
  168. // Done with the package.
  169. m_Package = NULL;
  170. }
  171. /**
  172. * Simplify indentation printing by allowing Indentation objects to be added
  173. * to streams.
  174. */
  175. std::ostream& operator<<(std::ostream& os,
  176. const cmCableData::Indentation& indent)
  177. {
  178. indent.Print(os);
  179. return os;
  180. }