source: tags/ms_r17q2/SECEDIT/SEC_abspos.cxx

Last change on this file was 15176, checked in by westram, 8 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.0 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : SEC_abspos.cxx                                    //
4//   Purpose   : Encapsulates helix position access                //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in July 2007      //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#include "SEC_abspos.hxx"
13
14#include <arb_mem.h>
15
16#include <cstdlib>
17#include <cstring>
18
19using namespace std;
20
21void XString::set_length(size_t len) {
22    if (number_found && x_string_len<len) freenull(number_found);
23    x_string_len = len;
24    initialized  = false;
25}
26
27XString::XString(size_t ali_length)
28    : abspos(0)
29    , number_found(0)
30{
31    int len = ali_length+1; // need one more (cause 'x's are written behind position)
32    ARB_alloc(x_string, len+1);
33    memset(x_string, '.', len);
34    x_string[len] = 0;
35    set_length(len);
36    initialize();
37}
38
39XString::XString(const char *saved_x_string, size_t saved_length, size_t ali_length)
40    : abspos(0)
41    , number_found(0)
42{
43    size_t xlen = ali_length+1;
44
45    sec_assert(saved_length == strlen(saved_x_string));
46    sec_assert(saved_length == xlen || saved_length == xlen-1);
47
48    ARB_alloc(x_string, xlen+1);
49    memcpy(x_string, saved_x_string, saved_length+1);
50
51    if (saved_length == xlen-1) { // normal case
52        x_string[xlen-1] = '.'; // additional position is a gap (SAI 'HELIX' should have a gap at end)
53        x_string[xlen]   = 0;   // (see also comments in get_x_string())
54    }
55
56    set_length(xlen);
57    initialize();
58}
59
60void XString::initialize()
61{
62    // detect number of 'x's in x_string :
63    {
64        size_t len = 0;
65        int    x   = 0;
66
67        while (char c = x_string[len]) {
68            if (c == 'x') x++;
69            len++;
70        }
71
72        sec_assert(len == x_string_len);
73
74        if (abspos) { // re-initialization
75            if (x_count<x) freenull(abspos); // abspos array too small
76        }
77        x_count = x;
78    }
79
80    if (!abspos)       ARB_alloc(abspos, x_count);
81    if (!number_found) ARB_alloc(number_found, x_string_len);
82
83    // init abspos and number_found :
84    {
85        int pos = 0;
86        int x   = 0;
87
88        while (char c = x_string[pos]) {
89            number_found[pos] = x;
90            if (c == 'x') {
91                abspos[x] = pos;
92                x++;
93            }
94            pos++;
95        }
96    }
97
98    initialized = true;
99}
100
101XString::~XString()
102{
103    free(x_string);
104    free(abspos);
105    free(number_found);
106}
107
108size_t XString::getAbsPos(int x) const
109{
110    sec_assert(initialized);
111    sec_assert(x >= 0 && x<x_count);
112    size_t pos = abspos[x];
113    sec_assert(pos<x_string_len);
114    return pos;
115}
116
117int XString::getXleftOf(size_t pos) const
118{
119    sec_assert(initialized);
120    sec_assert(pos<x_string_len);
121    int x = number_found[pos];
122    sec_assert(x >= 0 && x<x_count);
123    return x;
124}
125
126const char *XString::get_x_string() const {
127    sec_assert(initialized);
128
129    static char   *copy       = 0;
130    static size_t  copy_alloc = 0;
131
132    size_t bufsize = x_string_len+1;
133
134    if (!copy || copy_alloc<bufsize) {
135        freeset(copy, ARB_alloc<char>(bufsize));
136        copy_alloc = bufsize;
137    }
138
139    memcpy(copy, x_string, x_string_len+1);
140
141    int add_pos = x_string_len-1;
142
143    if (copy[add_pos] == '.') { // can be removed - added again after reload
144        copy[add_pos] = 0; // hide internal additional position
145    }
146    else {
147        // happens only if there's a helix on last alignment position.
148        // In this case we save the additional position to DB, which will
149        // lead the user to reformat his alignment (which will add a gap
150        // at end of SAI HELIX)
151    }
152    return copy;
153}
154
Note: See TracBrowser for help on using the repository browser.