source: tags/ms_r18q1/SECEDIT/SEC_abspos.cxx

Last change on this file was 16766, checked in by westram, 6 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(NULp),
29    number_found(NULp)
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(NULp),
41    number_found(NULp)
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    // detect number of 'x's in x_string :
62    {
63        size_t len = 0;
64        int    x   = 0;
65
66        while (char c = x_string[len]) {
67            if (c == 'x') x++;
68            len++;
69        }
70
71        sec_assert(len == x_string_len);
72
73        if (abspos) { // re-initialization
74            if (x_count<x) freenull(abspos); // abspos array too small
75        }
76        x_count = x;
77    }
78
79    if (!abspos)       ARB_alloc(abspos, x_count);
80    if (!number_found) ARB_alloc(number_found, x_string_len);
81
82    // init abspos and number_found :
83    {
84        int pos = 0;
85        int x   = 0;
86
87        while (char c = x_string[pos]) {
88            number_found[pos] = x;
89            if (c == 'x') {
90                abspos[x] = pos;
91                x++;
92            }
93            pos++;
94        }
95    }
96
97    initialized = true;
98}
99
100XString::~XString() {
101    free(x_string);
102    free(abspos);
103    free(number_found);
104}
105
106size_t XString::getAbsPos(int x) const {
107    sec_assert(initialized);
108    sec_assert(x >= 0 && x<x_count);
109    size_t pos = abspos[x];
110    sec_assert(pos<x_string_len);
111    return pos;
112}
113
114int XString::getXleftOf(size_t pos) const {
115    sec_assert(initialized);
116    sec_assert(pos<x_string_len);
117    int x = number_found[pos];
118    sec_assert(x >= 0 && x<x_count);
119    return x;
120}
121
122const char *XString::get_x_string() const {
123    sec_assert(initialized);
124
125    static char   *copy       = NULp;
126    static size_t  copy_alloc = 0;
127
128    size_t bufsize = x_string_len+1;
129
130    if (!copy || copy_alloc<bufsize) {
131        freeset(copy, ARB_alloc<char>(bufsize));
132        copy_alloc = bufsize;
133    }
134
135    memcpy(copy, x_string, x_string_len+1);
136
137    int add_pos = x_string_len-1;
138
139    if (copy[add_pos] == '.') { // can be removed - added again after reload
140        copy[add_pos] = 0; // hide internal additional position
141    }
142    else {
143        // happens only if there's a helix on last alignment position.
144        // In this case we save the additional position to DB, which will
145        // lead the user to reformat his alignment (which will add a gap
146        // at end of SAI HELIX)
147    }
148    return copy;
149}
150
Note: See TracBrowser for help on using the repository browser.