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