Warning, /include/Geant4/tools/wroot/free_seg is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_wroot_free_seg
0005 #define tools_wroot_free_seg
0006
0007 #include "seek"
0008 #include "wbuf"
0009 #include "../forit"
0010
0011 #include <ostream>
0012
0013 namespace tools {
0014 namespace wroot {
0015
0016 class free_seg {
0017 public:
0018 free_seg(std::ostream& a_out,seek a_first,seek a_last)
0019 :m_out(a_out),m_first(a_first),m_last(a_last){}
0020 virtual ~free_seg(){}
0021 public:
0022 free_seg(const free_seg& a_from)
0023 :m_out(a_from.m_out),m_first(a_from.m_first),m_last(a_from.m_last)
0024 {}
0025 free_seg& operator=(const free_seg& a_from){
0026 m_first = a_from.m_first;
0027 m_last = a_from.m_last;
0028 return *this;
0029 }
0030 public:
0031 std::ostream& out() const {return m_out;}
0032
0033 seek first() const {return m_first;}
0034 seek last() const {return m_last;}
0035
0036 void set_first(seek a_v) {m_first = a_v;}
0037 void set_last(seek a_v) {m_last = a_v;}
0038
0039 unsigned int record_size() const {
0040 if((m_first>START_BIG_FILE())|| //GB
0041 (m_last>START_BIG_FILE()) ){
0042 return sizeof(short) + 2 * sizeof(seek);
0043 } else {
0044 return sizeof(short) + 2 * sizeof(seek32);
0045 }
0046 }
0047
0048 bool fill_buffer(wbuf& a_wb) {
0049 short version = 1;
0050
0051 if((m_first>START_BIG_FILE())||
0052 (m_last>START_BIG_FILE())) version += big_file_version_tag();
0053
0054 if(!a_wb.write(version)) return false;
0055
0056 if(version>(short)big_file_version_tag()) {
0057 if(!a_wb.write(m_first)) return false;
0058 if(!a_wb.write(m_last)) return false;
0059 } else {
0060 if(m_first>START_BIG_FILE()) { //GB
0061 m_out << "tools::wroot::free_seg::fill_buffer :"
0062 << " attempt to write big Seek "
0063 << m_first << " on 32 bits."
0064 << std::endl;
0065 return false;
0066 }
0067 if(!a_wb.write((seek32)m_first)) return false;
0068 if(m_last>START_BIG_FILE()) { //GB
0069 m_out << "tools::wroot::free_seg::fill_buffer :"
0070 << " attempt to write big seek "
0071 << m_last << " on 32 bits."
0072 << std::endl;
0073 return false;
0074 }
0075 if(!a_wb.write((seek32)m_last)) return false;
0076 }
0077
0078 return true;
0079 }
0080
0081 protected:
0082 std::ostream& m_out;
0083 seek m_first; //First free word of segment
0084 seek m_last; //Last free word of segment
0085 };
0086
0087 }}
0088
0089 #include <list>
0090
0091 namespace tools {
0092 namespace wroot {
0093
0094 inline free_seg* find_after(const std::list<free_seg*>& a_list,free_seg* a_what) {
0095 tools_lforcit(free_seg*,a_list,it) {
0096 if((*it)==a_what) {
0097 it++;
0098 if(it==a_list.end()) return 0;
0099 return *it;
0100 }
0101 }
0102 return 0;
0103 }
0104
0105 inline void remove(std::list<free_seg*>& a_list,free_seg* a_what) {
0106 //NOTE : it does not delete a_what.
0107 tools_lforit(free_seg*,a_list,it) {
0108 if((*it)==a_what) {
0109 a_list.erase(it);
0110 return;
0111 }
0112 }
0113 }
0114
0115 inline void add_before(std::list<free_seg*>& a_list,free_seg* a_what,free_seg* a_new) {
0116 tools_lforit(free_seg*,a_list,it) {
0117 if((*it)==a_what) {
0118 a_list.insert(it,a_new);
0119 return;
0120 }
0121 }
0122 }
0123
0124 inline free_seg* add_free(std::list<free_seg*>& a_list,seek a_first,seek a_last) {
0125 // Add a new free segment to the list of free segments
0126 // ===================================================
0127 // If last just preceedes an existing free segment, then first becomes
0128 // the new starting location of the free segment.
0129 // if first just follows an existing free segment, then last becomes
0130 // the new ending location of the free segment.
0131 // if first just follows an existing free segment AND last just preceedes
0132 // an existing free segment, these two segments are merged into
0133 // one single segment.
0134 //
0135
0136 free_seg* idcur = a_list.front();
0137
0138 while (idcur) {
0139 seek curfirst = idcur->first();
0140 seek curlast = idcur->last();
0141 if (curlast == (a_first-1)) {
0142 idcur->set_last(a_last);
0143 free_seg* idnext = find_after(a_list,idcur);
0144 if (idnext == 0) return idcur;
0145 if (idnext->first() > (a_last+1)) return idcur;
0146 idcur->set_last(idnext->last());
0147 remove(a_list,idnext); //idnext not deleted.
0148 delete idnext;
0149 return idcur;
0150 }
0151 if (curfirst == (a_last+1)) {
0152 idcur->set_first(a_first);
0153 return idcur;
0154 }
0155 if (a_first < curfirst) {
0156 free_seg* newfree = new free_seg(idcur->out(),a_first,a_last);
0157 add_before(a_list,idcur,newfree);
0158 return newfree;
0159 }
0160 idcur = find_after(a_list,idcur);
0161 }
0162
0163 return 0;
0164 }
0165
0166
0167 }}
0168
0169 #endif