00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "gn/gnDefs.h"
00014
00015 #include <string>
00016 #include <vector>
00017 #include "gn/gnMultiSpec.h"
00018 #include "gn/gnBaseSource.h"
00019 #include "gn/gnBaseFeature.h"
00020 #include "gn/gnDebug.h"
00021 #include "gn/gnException.h"
00022
00023 void gnMultiSpec::Clear()
00024 {
00025 gnBaseSpec::Clear();
00026 uint32 list_size = m_headerList.size();
00027 for(uint32 i=0; i < list_size; i++)
00028 delete m_headerList[i];
00029 m_headerList.clear();
00030 }
00031
00032 gnSeqI gnMultiSpec::GetLength() const
00033 {
00034 gnSeqI subLen = 0;
00035 for(uint32 i=0; i < GetSpecListLength(); i++)
00036 subLen += GetSpec(i)->GetLength();
00037 return subLen;
00038 }
00039
00040
00041 uint32 gnMultiSpec::GetSpecIndexByBase( const gnSeqI baseI ) const{
00042 gnSeqI cur_length = 0;
00043 for(uint32 i=0; i < GetSpecListLength(); i++){
00044 cur_length += GetSpec(i)->GetLength();
00045 if(baseI < cur_length)
00046 return i;
00047 }
00048
00049 Throw_gnEx(SeqIndexOutOfBounds());
00050 }
00051
00052 uint32 gnMultiSpec::GetSpecIndexByName( const string& name ) const{
00053 for(uint32 i=0; i < GetSpecListLength(); i++){
00054 if(name == GetSpec(i)->GetName())
00055 return i;
00056 }
00057 Throw_gnEx(SpecIndexOutOfBounds());
00058 }
00059
00060
00061 gnSeqI gnMultiSpec::GetSpecStartBase( const uint32 specI ) const{
00062 uint32 i;
00063 if(specI >= GetSpecListLength())
00064 Throw_gnEx(SpecIndexOutOfBounds());
00065
00066 gnSeqI start_base = 0;
00067 for(i=0; i < specI; i++){
00068 start_base += GetSpec(i)->GetLength();
00069 }
00070 return start_base;
00071 }
00072
00073 gnSeqI gnMultiSpec::GetSpecEndBase( const uint32 specI ) const{
00074 uint32 i;
00075 if(specI >= GetSpecListLength())
00076 Throw_gnEx(SpecIndexOutOfBounds());
00077
00078 gnSeqI end_base = 0;
00079 for(i=0; i <= specI; i++){
00080 end_base += GetSpec(i)->GetLength();
00081 }
00082 return end_base;
00083 }
00084
00085 void gnMultiSpec::CropStart( gnSeqI cropLen ){
00086 gnSeqI curbase = 0;
00087 for(uint32 specI = 0; specI < GetSpecListLength(); specI++){
00088 curbase += GetSpec(specI)->GetLength();
00089 if(curbase <= cropLen){
00090
00091 gnBaseSpec *tmp_spec = GetSpec(specI);
00092 RemoveSpec(specI);
00093 delete tmp_spec;
00094 specI--;
00095 }else{
00096
00097 gnSeqI sub_len = cropLen - (curbase - GetSpec(specI)->GetLength());
00098 GetSpec(specI)->CropStart(sub_len);
00099 break;
00100 }
00101 }
00102 }
00103
00104 void gnMultiSpec::CropEnd( gnSeqI cropLen ){
00105 gnSeqI curbase = 0;
00106 gnSeqI cropbase = GetLength() - cropLen;
00107 boolean trash_the_rest = false;
00108 for(uint32 specI = 0; specI < GetSpecListLength(); specI++){
00109 curbase += GetSpec(specI)->GetLength();
00110 if(trash_the_rest){
00111
00112 gnBaseSpec *tmp_spec = GetSpec(specI);
00113 RemoveSpec(specI);
00114 delete tmp_spec;
00115 specI--;
00116 continue;
00117 }else if(curbase > cropbase){
00118 GetSpec(specI)->CropEnd(curbase - cropbase);
00119 trash_the_rest = true;
00120 }else if(curbase == cropbase)
00121 trash_the_rest = true;
00122 }
00123 }
00124
00125 void gnMultiSpec::AddHeader( gnBaseHeader* head, const uint32 i)
00126 {
00127 uint32 index = i == UINT32_MAX ? m_headerList.size() : i;
00128 m_headerList.insert(m_headerList.begin() + index, head);
00129 }
00130
00131 gnBaseHeader* gnMultiSpec::GetHeader( const string& name, uint32& i) const{
00132 for(; i < m_headerList.size(); i++){
00133 if( m_headerList[i]->GetHeaderName() == name)
00134 return m_headerList[i];
00135 }
00136 Throw_gnEx(HeaderIndexOutOfBounds());
00137 }
00138
00139 void gnMultiSpec::RemoveHeader( uint32 i)
00140 {
00141 if(i <= m_headerList.size()){
00142 m_headerList.erase(m_headerList.begin() + i);
00143 }
00144 Throw_gnEx(HeaderIndexOutOfBounds());
00145 }
00146
00147 boolean gnMultiSpec::SeqRead(const gnSeqI start, gnSeqC* buf, uint32& bufLen, const uint32 contigI ) const{
00148 if( bufLen == 0 )
00149 return true;
00150 if(contigI == ALL_CONTIGS){
00151 gnSeqI curpos = 0;
00152 uint32 readBytes = 0;
00153 uint32 remainingBytes = bufLen;
00154 uint32 curSpecI = 0;
00155
00156 for(curSpecI=0; curSpecI < GetSpecListLength(); curSpecI++){
00157 curpos += GetSpec(curSpecI)->GetLength();
00158 if(curpos > start)
00159 break;
00160 }
00161 if(curpos <= start)
00162 Throw_gnEx(SeqIndexOutOfBounds());
00163
00164 while((remainingBytes > 0) && (curSpecI < GetSpecListLength())) {
00165 gnSeqI readable = GetSpec(curSpecI)->GetLength();
00166
00167 uint32 start_pos = readBytes == 0 ? start - (curpos - readable) : 0;
00168 uint32 to_read = readable - start_pos >= remainingBytes ? remainingBytes : readable - start_pos;
00169 boolean success = GetSpec(curSpecI)->SeqRead(start_pos, buf+readBytes, to_read, contigI);
00170
00171 readBytes += to_read;
00172 remainingBytes -= to_read;
00173 if(!success)
00174 break;
00175 curSpecI++;
00176 }
00177 bufLen = readBytes;
00178 return true;
00179 }else{
00180 if(contigI < GetSpecListLength())
00181 return GetSpec(contigI)->SeqRead(start, buf, bufLen, ALL_CONTIGS);
00182 else
00183 Throw_gnEx(SpecIndexOutOfBounds());
00184 }
00185 return false;
00186 }
00187