1 #ifndef SRA__READER__SRA__VDBREAD__HPP
2 #define SRA__READER__SRA__VDBREAD__HPP
3 /*  $Id: vdbread.hpp 632481 2021-06-02 11:13:44Z ivanov $
4  * ===========================================================================
5  *
6  *                            PUBLIC DOMAIN NOTICE
7  *               National Center for Biotechnology Information
8  *
9  *  This software/database is a "United States Government Work" under the
10  *  terms of the United States Copyright Act.  It was written as part of
11  *  the author's official duties as a United States Government employee and
12  *  thus cannot be copyrighted.  This software/database is freely available
13  *  to the public for use. The National Library of Medicine and the U.S.
14  *  Government have not placed any restriction on its use or reproduction.
15  *
16  *  Although all reasonable efforts have been taken to ensure the accuracy
17  *  and reliability of the software and data, the NLM and the U.S.
18  *  Government do not and cannot warrant the performance or results that
19  *  may be obtained by using this software or data. The NLM and the U.S.
20  *  Government disclaim all warranties, express or implied, including
21  *  warranties of performance, merchantability or fitness for any particular
22  *  purpose.
23  *
24  *  Please cite the author in any work or product based on this material.
25  *
26  * ===========================================================================
27  *
28  * Authors:  Eugene Vasilchenko
29  *
30  * File Description:
31  *   Access to VDB files
32  *
33  */
34 
35 #include <corelib/ncbistd.hpp>
36 #include <corelib/ncbiobj.hpp>
37 #include <sra/readers/sra/exception.hpp>
38 #include <sra/readers/sra/sdk.hpp>
39 #include <vector>
40 
41 // SRA SDK structures
42 struct KConfig;
43 struct KDBManager;
44 struct KNSManager;
45 struct VFSManager;
46 struct VDBManager;
47 struct VPath;
48 struct VResolver;
49 struct VDatabase;
50 struct VTable;
51 struct VCursor;
52 struct KIndex;
53 
54 BEGIN_NCBI_SCOPE
55 BEGIN_SCOPE(objects)
56 
57 DECLARE_SRA_REF_TRAITS(VDBManager, const);
58 DECLARE_SRA_REF_TRAITS(VDatabase, const);
59 DECLARE_SRA_REF_TRAITS(VTable, const);
60 DECLARE_SRA_REF_TRAITS(VCursor, const);
61 DECLARE_SRA_REF_TRAITS(KIndex, const);
62 DECLARE_SRA_REF_TRAITS(KConfig, );
63 DECLARE_SRA_REF_TRAITS(KDBManager, const);
64 DECLARE_SRA_REF_TRAITS(KNSManager, );
65 DECLARE_SRA_REF_TRAITS(VFSManager, );
66 DECLARE_SRA_REF_TRAITS(VPath, const);
67 DECLARE_SRA_REF_TRAITS(VResolver, );
68 
69 
70 class CVFSManager;
71 class CVPath;
72 class CVResolver;
73 
74 class CVDBMgr;
75 class CVDB;
76 class CVDBTable;
77 class CVDBColumn;
78 class CVDBCursor;
79 class CVDBStringValue;
80 
81 typedef int64_t TVDBRowId;
82 typedef uint64_t TVDBRowCount;
83 typedef pair<TVDBRowId, TVDBRowCount> TVDBRowIdRange;
84 typedef uint32_t TVDBColumnIdx;
85 
86 class NCBI_SRAREAD_EXPORT CKDBManager
87     : public CSraRef<const KDBManager>
88 {
89 public:
90     explicit CKDBManager(const CVDBMgr& mgr);
CKDBManager(ENull)91     explicit CKDBManager(ENull /*null*/)
92         {
93         }
94 };
95 
96 
97 class NCBI_SRAREAD_EXPORT CKNSManager
98     : public CSraRef<KNSManager>
99 {
100 public:
101     explicit CKNSManager(const CVFSManager& mgr);
CKNSManager(ENull)102     explicit CKNSManager(ENull /*null*/)
103         {
104         }
105     enum EMake {
106         eMake
107     };
108     explicit CKNSManager(EMake make);
109 };
110 
111 
112 class NCBI_SRAREAD_EXPORT CVFSManager
113     : public CSraRef<VFSManager>
114 {
115 public:
116     NCBI_DEPRECATED_CTOR(CVFSManager(void));
117     explicit CVFSManager(const CVDBMgr& mgr);
118     enum ECreateNew {
119         eCreateNew
120     };
121     explicit CVFSManager(ECreateNew);
CVFSManager(ENull)122     explicit CVFSManager(ENull /*null*/)
123         {
124         }
125 
126 private:
127     void x_InitNew(void);
128 };
129 
130 
131 class NCBI_SRAREAD_EXPORT CVPath
132     : public CSraRef<const VPath>
133 {
134     typedef CSraRef<const VPath> TParent;
135 public:
CVPath(void)136     CVPath(void)
137         {
138         }
CVPath(ENull)139     CVPath(ENull /*null*/)
140         {
141         }
142     explicit
CVPath(const VPath * path)143     CVPath(const VPath* path)
144         : TParent(path)
145         {
146         }
147     enum EType {
148         eSys, // OS native filesystem path
149         eAcc, // VDB accession, needs to be resolved to actual path
150         ePath // VDB path string
151     };
152     CVPath(const CVFSManager& mgr, const string& path, EType type = eSys);
153     NCBI_DEPRECATED_CTOR(explicit CVPath(const string& path, EType type = eSys));
154 
155     bool IsLocalFile() const;
156     string ToString(EType type = eSys) const;
157 
158     // Check if argument string is plain VDB accession,
159     // otherwise it's a system path.
160     static bool IsPlainAccession(const string& acc_or_path);
161 
162     // Convert system path to a POSIX path, accepted by VDB.
163     // Note that only MS Windows requires this conversion.
164     static string ConvertSysPathToPOSIX(const string& sys_path);
165 
166     // Convert system path to a POSIX path, accepted by VDB.
167     // Note that only MS Windows requires this conversion.
168     // Keep plain VDB accession unchanged.
169     static string ConvertAccOrSysPathToPOSIX(const string& acc_or_path);
170 
171 private:
172     void x_Init(const CVFSManager& mgr, const string& path, EType type);
173 };
174 
175 
176 class NCBI_SRAREAD_EXPORT CKConfig
177     : public CSraRef<KConfig>
178 {
179 public:
180     NCBI_DEPRECATED_CTOR(CKConfig(void));
181     explicit CKConfig(const CVDBMgr& mgr);
CKConfig(ENull)182     explicit CKConfig(ENull /*null*/)
183         {
184         }
185     enum EMake {
186         eMake
187     };
188     explicit CKConfig(EMake make);
189 
190     // Commit changes made into config file
191     void Commit() const;
192 };
193 
194 
195 class NCBI_SRAREAD_EXPORT CVResolver
196     : public CSraRef<VResolver>
197 {
198 public:
199     explicit CVResolver(const CVFSManager& mgr);
200     NCBI_DEPRECATED_CTOR(CVResolver(const CVFSManager& mgr, const CKConfig& cfg));
CVResolver(ENull)201     explicit CVResolver(ENull /*null*/)
202         : m_Mgr(null)
203         {
204         }
205 
206     // Resolve VDB accession to POSIX path.
207     // Keep non plain accession string unchanged.
208     string Resolve(const string& acc) const;
209 
210 private:
211     CVFSManager m_Mgr;
212 };
213 
214 
215 class NCBI_SRAREAD_EXPORT CVDBMgr
216     : public CSraRef<const VDBManager>
217 {
218 public:
219     CVDBMgr(void);
220 
221     string FindAccPath(const string& acc) const;
222 
Close(void)223     void Close(void) {
224         Release();
225     }
226 
227 
228     // Get VDB cache root OS native filesystem path
229     // returns empty string if no cache is set
230     string GetCacheRoot() const;
231 
232     // Set VDB cache root OS native filesystem path
233     void SetCacheRoot(const string& path);
234 
235     // Delete old cache files
236     void DeleteCacheOlderThan(Uint4 days);
237 
238     // Commit configuration changes into config file
239     void CommitConfig() const;
240 
241 protected:
242     void x_Init(void);
243 
244 private:
245     mutable CVResolver m_Resolver;
246 };
247 
248 
249 class NCBI_SRAREAD_EXPORT CVDB
250     : public CSraRef<const VDatabase>
251 {
252 public:
CVDB(void)253     CVDB(void)
254         {
255         }
256     CVDB(const CVDBMgr& mgr, const string& acc_or_path);
257 
GetName(void) const258     const string& GetName(void) const
259         {
260             return m_Name;
261         }
GetFullName(void) const262     const string& GetFullName(void) const
263         {
264             return m_Name;
265         }
266     CNcbiOstream& PrintFullName(CNcbiOstream& out) const;
267 
Close(void)268     void Close(void) {
269         *this = CVDB();
270     }
271 
272 private:
273     string m_Name;
274 };
275 
276 
277 class NCBI_SRAREAD_EXPORT CVDBTable
278     : public CSraRef<const VTable>
279 {
280 public:
281     enum EMissing {
282         eMissing_Throw,
283         eMissing_Allow
284     };
285 
CVDBTable(void)286     CVDBTable(void)
287         {
288         }
289     CVDBTable(const CVDB& db,
290               const char* table_name,
291               EMissing missing = eMissing_Throw);
292     CVDBTable(const CVDBMgr& mgr,
293               const string& acc_or_path,
294               EMissing missing = eMissing_Throw);
295 
GetDb(void) const296     const CVDB& GetDb(void) const
297         {
298             return m_Db;
299         }
GetName(void) const300     const string& GetName(void) const
301         {
302             return m_Name;
303         }
304     string GetFullName(void) const;
305     CNcbiOstream& PrintFullName(CNcbiOstream& out) const;
306 
Close(void)307     void Close(void) {
308         *this = CVDBTable();
309     }
310 
311 public:
312     CVDB m_Db;
313     string m_Name;
314 };
315 
316 
317 class NCBI_SRAREAD_EXPORT CVDBTableIndex
318     : public CSraRef<const KIndex>
319 {
320 public:
321     enum EMissing {
322         eMissing_Throw,
323         eMissing_Allow
324     };
325 
CVDBTableIndex(void)326     CVDBTableIndex(void)
327         {
328         }
329     CVDBTableIndex(const CVDBTable& table,
330                    const char* index_name,
331                    EMissing missing = eMissing_Throw);
332 
GetTable(void) const333     const CVDBTable& GetTable(void) const
334         {
335             return m_Table;
336         }
GetName(void) const337     const char* GetName(void) const
338         {
339             return m_Name;
340         }
341     string GetFullName(void) const;
342     CNcbiOstream& PrintFullName(CNcbiOstream& out) const;
343 
344     TVDBRowIdRange Find(const string& value) const;
345 
Close(void)346     void Close(void) {
347         *this = CVDBTableIndex();
348     }
349 
350 private:
351     CVDBTable m_Table;
352     const char* m_Name;
353 };
354 
355 
356 class NCBI_SRAREAD_EXPORT CVDBCursor
357     : public CSraRef<const VCursor>
358 {
359 public:
CVDBCursor(void)360     CVDBCursor(void)
361         : m_RowOpened(false)
362         {
363         }
CVDBCursor(const CVDBTable & table)364     explicit CVDBCursor(const CVDBTable& table)
365         : m_RowOpened(false)
366         {
367             Init(table);
368         }
369 
GetTable(void) const370     const CVDBTable& GetTable(void) const
371         {
372             return m_Table;
373         }
374 
RowIsOpened(void) const375     bool RowIsOpened(void) const
376         {
377             return m_RowOpened;
378         }
379     rc_t OpenRowRc(TVDBRowId row_id);
380     void OpenRow(TVDBRowId row_id);
TryOpenRow(TVDBRowId row_id)381     bool TryOpenRow(TVDBRowId row_id)
382         {
383             return OpenRowRc(row_id) == 0;
384         }
385     void CloseRow(void);
386 
387     // returns first id, and count of ids in the range
388     TVDBRowIdRange GetRowIdRange(TVDBColumnIdx column = 0) const;
389 
390     TVDBRowId GetMaxRowId(void) const;
391 
392     void SetParam(const char* name, const CTempString& value) const;
393 
394     uint32_t GetElementCount(TVDBRowId row, const CVDBColumn& column,
395                              uint32_t elem_bits) const;
396     void ReadElements(TVDBRowId row, const CVDBColumn& column,
397                       uint32_t elem_bits,
398                       uint32_t start, uint32_t count,
399                       void* buffer) const;
400 
Close(void)401     void Close(void) {
402         *this = CVDBCursor();
403     }
404 
405 protected:
406     void Init(const CVDBTable& table);
407 
408 private:
409     CVDBTable m_Table;
410     bool m_RowOpened;
411 };
412 
413 
414 class NCBI_SRAREAD_EXPORT CVDBObjectCacheBase
415 {
416 public:
417     CVDBObjectCacheBase(void);
418     ~CVDBObjectCacheBase(void);
419 
420     void Clear(void);
421 
422 protected:
423     CObject* Get(TVDBRowId row);
424     void Put(CObject* curs, TVDBRowId row);
425 
426 private:
427     typedef pair<TVDBRowId, CRef<CObject> > TSlot;
428     typedef vector<TSlot> TObjects;
429     TObjects m_Objects;
430 
431 private:
432     CVDBObjectCacheBase(const CVDBObjectCacheBase&);
433     void operator=(const CVDBObjectCacheBase&);
434 };
435 
436 
437 template<class Object>
438 class CVDBObjectCache : public CVDBObjectCacheBase
439 {
440 public:
Get(TVDBRowId row=0)441     CRef<Object> Get(TVDBRowId row = 0) {
442         Object* obj = static_cast<Object*>(CVDBObjectCacheBase::Get(row));
443         return CRef<Object>(obj);
444     }
Put(CRef<Object> & ref,TVDBRowId row=0)445     void Put(CRef<Object>& ref, TVDBRowId row = 0) {
446         if ( Object* obj = ref.ReleaseOrNull() ) {
447             CVDBObjectCacheBase::Put(obj, row);
448         }
449     }
450 };
451 
452 
453 class NCBI_SRAREAD_EXPORT CVDBColumn
454 {
455 public:
456     enum EMissing {
457         eMissing_Throw,
458         eMissing_Allow
459     };
460 
461     enum {
462         kInvalidIndex = TVDBColumnIdx(~0)
463     };
464 
CVDBColumn(void)465     CVDBColumn(void)
466         : m_Name(0),
467           m_Index(kInvalidIndex)
468         {
469         }
CVDBColumn(const CVDBCursor & cursor,const char * name,EMissing missing)470     CVDBColumn(const CVDBCursor& cursor,
471                const char* name,
472                EMissing missing)
473         {
474             Init(cursor, 0, name, NULL, missing);
475         }
CVDBColumn(const CVDBCursor & cursor,const char * name,const char * backup_name=NULL,EMissing missing=eMissing_Throw)476     CVDBColumn(const CVDBCursor& cursor,
477                const char* name,
478                const char* backup_name = NULL,
479                EMissing missing = eMissing_Throw)
480         {
481             Init(cursor, 0, name, backup_name, missing);
482         }
CVDBColumn(const CVDBCursor & cursor,size_t element_bit_size,const char * name,const char * backup_name=NULL,EMissing missing=eMissing_Throw)483     CVDBColumn(const CVDBCursor& cursor,
484                size_t element_bit_size,
485                const char* name,
486                const char* backup_name = NULL,
487                EMissing missing = eMissing_Throw)
488         {
489             Init(cursor, element_bit_size, name, backup_name, missing);
490         }
491 
Reset(void)492     void Reset(void)
493         {
494             m_Index = kInvalidIndex;
495         }
496     void ResetIfAlwaysEmpty(const CVDBCursor& cursor);
497 
GetName(void) const498     const char* GetName(void) const
499         {
500             return m_Name;
501         }
502 
503     DECLARE_OPERATOR_BOOL(m_Index != kInvalidIndex);
504 
GetIndex(void) const505     TVDBColumnIdx GetIndex(void) const
506         {
507             return m_Index;
508         }
509 
510     // returns first id, and count of ids in the range
GetRowIdRange(const CVDBCursor & cursor) const511     TVDBRowIdRange GetRowIdRange(const CVDBCursor& cursor) const
512         {
513             return cursor.GetRowIdRange(GetIndex());
514         }
515 
516 protected:
517     void Init(const CVDBCursor& cursor,
518               size_t element_bit_size,
519               const char* name,
520               const char* backup_name,
521               EMissing missing);
522 
523 private:
524     const char* m_Name;
525     TVDBColumnIdx m_Index;
526 };
527 
528 
529 template<size_t ElementBitSize>
530 class CVDBColumnBits : public CVDBColumn
531 {
532 public:
CVDBColumnBits(void)533     CVDBColumnBits(void)
534         {
535         }
CVDBColumnBits(const CVDBCursor & cursor,const char * name,const char * backup_name=NULL,EMissing missing=eMissing_Throw)536     CVDBColumnBits(const CVDBCursor& cursor,
537                    const char* name,
538                    const char* backup_name = NULL,
539                    EMissing missing = eMissing_Throw)
540         : CVDBColumn(cursor, ElementBitSize, name, backup_name, missing)
541         {
542         }
543 };
544 
545 
546 // DECLARE_VDB_COLUMN is helper macro to declare accessor to VDB column
547 #define DECLARE_VDB_COLUMN(name)                                        \
548     CVDBValue::SRef name(TVDBRowId row, CVDBValue::EMissing missing = CVDBValue::eMissing_Throw) const { \
549         return CVDBValue::SRef(m_Cursor, row, NCBI_NAME2(m_,name), missing); \
550     }                                                                   \
551     CVDBColumn NCBI_NAME2(m_, name)
552 
553 // DECLARE_VDB_COLUMN is helper macro to declare accessor to VDB column
554 #define DECLARE_VDB_COLUMN_AS(type, name)                               \
555     CVDBValueFor<type> name(TVDBRowId row, CVDBValue::EMissing missing = CVDBValue::eMissing_Throw) const { \
556         return CVDBValueFor<type>(m_Cursor, row, NCBI_NAME2(m_,name), missing); \
557     }                                                                   \
558     CVDBColumnBits<sizeof(type)*8> NCBI_NAME2(m_, name)
559 
560 // DECLARE_VDB_COLUMN is helper macro to declare accessor to VDB column
561 #define DECLARE_VDB_COLUMN_AS_STRING(name)                              \
562     CVDBStringValue name(TVDBRowId row, CVDBValue::EMissing missing = CVDBValue::eMissing_Throw) const { \
563         return CVDBStringValue(m_Cursor, row, NCBI_NAME2(m_,name), missing); \
564     }                                                                   \
565     CVDBColumnBits<8> NCBI_NAME2(m_, name)
566 
567 // DECLARE_VDB_COLUMN is helper macro to declare accessor to VDB column
568 #define DECLARE_VDB_COLUMN_AS_4BITS(name)                               \
569     CVDBValueFor4Bits name(TVDBRowId row) const {                       \
570         return CVDBValueFor4Bits(m_Cursor, row, NCBI_NAME2(m_,name));   \
571     }                                                                   \
572     CVDBColumnBits<4> NCBI_NAME2(m_, name)
573 
574 // INIT_VDB_COLUMN* are helper macros to initialize VDB column accessors
575 #define INIT_VDB_COLUMN(name)                   \
576     NCBI_NAME2(m_, name)(m_Cursor, #name)
577 #define INIT_VDB_COLUMN_BACKUP(name, backup_name)       \
578     NCBI_NAME2(m_, name)(m_Cursor, #name, #backup_name)
579 #define INIT_VDB_COLUMN_AS(name, type)                  \
580     NCBI_NAME2(m_, name)(m_Cursor, "("#type")"#name)
581 #define INIT_OPTIONAL_VDB_COLUMN(name)                                  \
582     NCBI_NAME2(m_, name)(m_Cursor, #name, NULL, CVDBColumn::eMissing_Allow)
583 #define INIT_OPTIONAL_VDB_COLUMN_BACKUP(name, backup_name)              \
584     NCBI_NAME2(m_, name)(m_Cursor, #name, #backup_name, CVDBColumn::eMissing_Allow)
585 #define INIT_OPTIONAL_VDB_COLUMN_AS(name, type)                         \
586     NCBI_NAME2(m_, name)(m_Cursor, "("#type")"#name, NULL, CVDBColumn::eMissing_Allow)
587 
588 
589 class NCBI_SRAREAD_EXPORT CVDBValue
590 {
591 public:
592     enum EMissing {
593         eMissing_Throw,
594         eMissing_Allow
595     };
596 
597     struct SRef {
SRefCVDBValue::SRef598         SRef(const CVDBCursor& cur,
599              TVDBRowId r,
600              const CVDBColumn& col)
601             : cursor(cur), column(col), row(r)
602             {
603             }
604 
605         const CVDBCursor& cursor;
606         const CVDBColumn& column;
607         TVDBRowId row;
608     };
609     struct SSaveRef {
SSaveRefCVDBValue::SSaveRef610         SSaveRef(void)
611             : m_Table(0), m_ColumnName(0), m_Row(0)
612             {
613             }
614 
SetCVDBValue::SSaveRef615         void Set(const CVDBCursor& cursor,
616                  TVDBRowId row,
617                  const CVDBColumn& column)
618             {
619                 m_Table = &cursor.GetTable();
620                 m_ColumnName = column.GetName();
621                 m_Row = row;
622             }
623 
624         CNcbiOstream& PrintFullName(CNcbiOstream& out) const;
625 
626         const CVDBTable* m_Table;
627         const char* m_ColumnName;
628         TVDBRowId m_Row;
629     };
CVDBValue(void)630     CVDBValue(void)
631         : m_Data(0),
632           m_ElemCount(0)
633         {
634         }
CVDBValue(const CVDBCursor & cursor,const CVDBColumn & column)635     CVDBValue(const CVDBCursor& cursor, const CVDBColumn& column)
636         : m_Data(0),
637           m_ElemCount(0)
638         {
639             x_Get(cursor, column);
640         }
CVDBValue(const CVDBCursor & cursor,TVDBRowId row,const CVDBColumn & column,EMissing missing=eMissing_Throw)641     CVDBValue(const CVDBCursor& cursor, TVDBRowId row,
642               const CVDBColumn& column, EMissing missing = eMissing_Throw)
643         : m_Data(0),
644           m_ElemCount(0)
645         {
646             x_Get(cursor, row, column, missing);
647         }
CVDBValue(const SRef & ref)648     explicit CVDBValue(const SRef& ref)
649         : m_Data(0),
650           m_ElemCount(0)
651         {
652             x_Get(ref.cursor, ref.row, ref.column);
653         }
CVDBValue(const CVDBCursor & cursor,const char * param_name,const CTempString & param_value,const CVDBColumn & column)654     CVDBValue(const CVDBCursor& cursor,
655               const char* param_name, const CTempString& param_value,
656               const CVDBColumn& column)
657         : m_Data(0),
658           m_ElemCount(0)
659         {
660             cursor.SetParam(param_name, param_value);
661             x_Get(cursor, column);
662         }
663 
empty(void) const664     bool empty(void) const
665         {
666             return !m_ElemCount;
667         }
size(void) const668     size_t size(void) const
669         {
670             return m_ElemCount;
671         }
672 
PrintFullName(CNcbiOstream & out) const673     CNcbiOstream& PrintFullName(CNcbiOstream& out) const
674         {
675             return m_Ref.PrintFullName(out);
676         }
677 
678 protected:
679     void x_Get(const CVDBCursor& cursor,
680                const CVDBColumn& column);
681     void x_Get(const CVDBCursor& cursor,
682                TVDBRowId row,
683                const CVDBColumn& column,
684                EMissing missing = eMissing_Throw);
685 
686     void x_ReportIndexOutOfBounds(size_t index) const;
687     void x_ReportNotOneValue(void) const;
x_CheckIndex(size_t index) const688     void x_CheckIndex(size_t index) const
689         {
690             if ( index >= size() ) {
691                 x_ReportIndexOutOfBounds(index);
692             }
693         }
694     void x_CheckRange(size_t pos, size_t len) const;
x_CheckOneValue(void) const695     void x_CheckOneValue(void) const
696         {
697             if ( size() != 1 ) {
698                 x_ReportNotOneValue();
699             }
700         }
701 
702     SSaveRef m_Ref;
703     const void* m_Data;
704     uint32_t m_ElemCount;
705 };
706 
707 
708 class NCBI_SRAREAD_EXPORT CVDBValueFor4Bits
709 {
710 public:
711     typedef unsigned TValue;
712 
CVDBValueFor4Bits(void)713     CVDBValueFor4Bits(void)
714         : m_RawData(0),
715           m_ElemOffset(0),
716           m_ElemCount(0)
717         {
718         }
CVDBValueFor4Bits(const CVDBValue::SRef & ref)719     explicit CVDBValueFor4Bits(const CVDBValue::SRef& ref)
720         : m_RawData(0),
721           m_ElemOffset(0),
722           m_ElemCount(0)
723         {
724             x_Get(ref.cursor, ref.row, ref.column);
725         }
CVDBValueFor4Bits(const CVDBCursor & cursor,TVDBRowId row,const CVDBColumn & column)726     CVDBValueFor4Bits(const CVDBCursor& cursor, TVDBRowId row,
727                       const CVDBColumn& column)
728         : m_RawData(0),
729           m_ElemOffset(0),
730           m_ElemCount(0)
731         {
732             x_Get(cursor, row, column);
733         }
734 
raw_data(void) const735     const char* raw_data(void) const
736         {
737             return m_RawData;
738         }
raw_offset(void) const739     uint32_t raw_offset(void) const
740         {
741             return m_ElemOffset;
742         }
size(void) const743     uint32_t size(void) const
744         {
745             return m_ElemCount;
746         }
empty(void) const747     bool empty(void) const
748         {
749             return !size();
750         }
751 
Value(size_t index) const752     TValue Value(size_t index) const
753         {
754             x_CheckIndex(index);
755             return x_ValueByRawIndex(index+raw_offset());
756         }
operator [](size_t index) const757     TValue operator[](size_t index) const
758         {
759             return Value(index);
760         }
761 
762     CVDBValueFor4Bits substr(size_t pos, size_t len) const;
763 
PrintFullName(CNcbiOstream & out) const764     CNcbiOstream& PrintFullName(CNcbiOstream& out) const
765         {
766             return m_Ref.PrintFullName(out);
767         }
768 
769 protected:
770     void x_Get(const CVDBCursor& cursor,
771                TVDBRowId row,
772                const CVDBColumn& column);
sub_value(uint8_t v,size_t sub_index)773     static TValue sub_value(uint8_t v, size_t sub_index)
774         {
775             return sub_index? (v&0xf): (v>>4);
776         }
x_ValueByRawIndex(size_t raw_index) const777     TValue x_ValueByRawIndex(size_t raw_index) const
778         {
779             return sub_value(raw_data()[raw_index/2], raw_index%2);
780         }
781 
782     void x_ReportIndexOutOfBounds(size_t index) const;
x_CheckIndex(size_t index) const783     void x_CheckIndex(size_t index) const
784         {
785             if ( index >= size() ) {
786                 x_ReportIndexOutOfBounds(index);
787             }
788         }
789     void x_CheckRange(size_t pos, size_t len) const;
790 
CVDBValueFor4Bits(const CVDBValue::SSaveRef & ref,const char * raw,uint32_t offset,uint32_t sz)791     CVDBValueFor4Bits(const CVDBValue::SSaveRef& ref,
792                       const char* raw, uint32_t offset, uint32_t sz)
793         : m_Ref(ref),
794           m_RawData(raw),
795           m_ElemOffset(offset),
796           m_ElemCount(sz)
797         {
798         }
799 
800     CVDBValue::SSaveRef m_Ref;
801     const char* m_RawData;
802     uint32_t m_ElemOffset;
803     uint32_t m_ElemCount;
804 };
805 
806 
807 class NCBI_SRAREAD_EXPORT CVDBValueFor2Bits
808 {
809 public:
810     typedef unsigned TValue;
811 
CVDBValueFor2Bits(void)812     CVDBValueFor2Bits(void)
813         : m_RawData(0),
814           m_ElemOffset(0),
815           m_ElemCount(0)
816         {
817         }
CVDBValueFor2Bits(const CVDBValue::SRef & ref)818     explicit CVDBValueFor2Bits(const CVDBValue::SRef& ref)
819         : m_RawData(0),
820           m_ElemOffset(0),
821           m_ElemCount(0)
822         {
823             x_Get(ref.cursor, ref.row, ref.column);
824         }
CVDBValueFor2Bits(const CVDBCursor & cursor,TVDBRowId row,const CVDBColumn & column)825     CVDBValueFor2Bits(const CVDBCursor& cursor, TVDBRowId row,
826                       const CVDBColumn& column)
827         : m_RawData(0),
828           m_ElemOffset(0),
829           m_ElemCount(0)
830         {
831             x_Get(cursor, row, column);
832         }
833 
raw_data(void) const834     const char* raw_data(void) const
835         {
836             return m_RawData;
837         }
raw_offset(void) const838     uint32_t raw_offset(void) const
839         {
840             return m_ElemOffset;
841         }
size(void) const842     uint32_t size(void) const
843         {
844             return m_ElemCount;
845         }
empty(void) const846     bool empty(void) const
847         {
848             return !size();
849         }
850 
Value(size_t index) const851     TValue Value(size_t index) const
852         {
853             x_CheckIndex(index);
854             return x_ValueByRawIndex(index+raw_offset());
855         }
operator [](size_t index) const856     TValue operator[](size_t index) const
857         {
858             return Value(index);
859         }
860 
861     CVDBValueFor2Bits substr(size_t pos, size_t len) const;
862 
PrintFullName(CNcbiOstream & out) const863     CNcbiOstream& PrintFullName(CNcbiOstream& out) const
864         {
865             return m_Ref.PrintFullName(out);
866         }
867 
868 protected:
869     void x_Get(const CVDBCursor& cursor,
870                TVDBRowId row,
871                const CVDBColumn& column);
sub_value(uint8_t v,size_t sub_index)872     static TValue sub_value(uint8_t v, size_t sub_index)
873         {
874             return (v>>(6-2*sub_index))&3;
875         }
x_ValueByRawIndex(size_t raw_index) const876     TValue x_ValueByRawIndex(size_t raw_index) const
877         {
878             return sub_value(raw_data()[raw_index/4], raw_index%4);
879         }
880 
881     void x_ReportIndexOutOfBounds(size_t index) const;
x_CheckIndex(size_t index) const882     void x_CheckIndex(size_t index) const
883         {
884             if ( index >= size() ) {
885                 x_ReportIndexOutOfBounds(index);
886             }
887         }
888     void x_CheckRange(size_t pos, size_t len) const;
889 
CVDBValueFor2Bits(const CVDBValue::SSaveRef & ref,const char * raw,uint32_t offset,uint32_t sz)890     CVDBValueFor2Bits(const CVDBValue::SSaveRef& ref,
891                       const char* raw, uint32_t offset, uint32_t sz)
892         : m_Ref(ref),
893           m_RawData(raw),
894           m_ElemOffset(offset),
895           m_ElemCount(sz)
896         {
897         }
898 
899     CVDBValue::SSaveRef m_Ref;
900     const char* m_RawData;
901     uint32_t m_ElemOffset;
902     uint32_t m_ElemCount;
903 };
904 
905 
906 template<class V>
907 class CVDBValueFor : public CVDBValue
908 {
909 public:
910     typedef V TValue;
CVDBValueFor(void)911     CVDBValueFor(void)
912         {
913         }
CVDBValueFor(const CVDBCursor & cursor,const CVDBColumn & column)914     CVDBValueFor(const CVDBCursor& cursor, const CVDBColumn& column)
915         : CVDBValue(cursor, column)
916         {
917         }
CVDBValueFor(const CVDBCursor & cursor,TVDBRowId row,const CVDBColumn & column,EMissing missing=eMissing_Throw)918     CVDBValueFor(const CVDBCursor& cursor, TVDBRowId row,
919                  const CVDBColumn& column, EMissing missing = eMissing_Throw)
920         : CVDBValue(cursor, row, column, missing)
921         {
922         }
CVDBValueFor(const CVDBValue::SRef & ref)923     explicit CVDBValueFor(const CVDBValue::SRef& ref)
924         : CVDBValue(ref)
925         {
926         }
CVDBValueFor(CVDBCursor & cursor,const char * param_name,const CTempString & param_value,const CVDBColumn & column)927     CVDBValueFor(CVDBCursor& cursor,
928                  const char* param_name, const CTempString& param_value,
929                  const CVDBColumn& column)
930         : CVDBValue(cursor, param_name, param_value, column)
931         {
932         }
933 
data() const934     const TValue* data() const
935         {
936             return static_cast<const TValue*>(m_Data);
937         }
operator [](size_t i) const938     const TValue& operator[](size_t i) const
939         {
940             x_CheckIndex(i);
941             return data()[i];
942         }
Value(void) const943     const TValue& Value(void) const
944         {
945             x_CheckOneValue();
946             return *data();
947         }
operator *(void) const948     const TValue& operator*(void) const
949         {
950             return Value();
951         }
operator ->(void) const952     const TValue* operator->(void) const
953         {
954             return &Value();
955         }
956 
operator const TValue&(void) const957     operator const TValue&(void) const
958         {
959             return Value();
960         }
961 
962     typedef const TValue* const_iterator;
begin() const963     const_iterator begin() const
964         {
965             return data();
966         }
end() const967     const_iterator end() const
968         {
969             return begin()+size();
970         }
971 
substr(size_t pos,size_t len) const972     CVDBValueFor<TValue> substr(size_t pos, size_t len) const
973         {
974             x_CheckRange(pos, len);
975             return CVDBValueFor<TValue>(data()+pos, uint32_t(len));
976         }
977 
978 private:
979     // to cause ambiguity if assigned to a wrong type
980     operator double(void) const;
981 };
982 
983 
984 class CVDBStringValue : public CVDBValueFor<char>
985 {
986 public:
CVDBStringValue(void)987     CVDBStringValue(void)
988         {
989         }
CVDBStringValue(const CVDBCursor & cursor,const CVDBColumn & column)990     CVDBStringValue(const CVDBCursor& cursor,
991                     const CVDBColumn& column)
992         : CVDBValueFor<char>(cursor, column)
993         {
994         }
CVDBStringValue(const CVDBCursor & cursor,TVDBRowId row,const CVDBColumn & column,EMissing missing=eMissing_Throw)995     CVDBStringValue(const CVDBCursor& cursor, TVDBRowId row,
996                     const CVDBColumn& column,
997                     EMissing missing = eMissing_Throw)
998         : CVDBValueFor<char>(cursor, row, column, missing)
999         {
1000         }
CVDBStringValue(const CVDBValue::SRef & ref)1001     explicit CVDBStringValue(const CVDBValue::SRef& ref)
1002         : CVDBValueFor<char>(ref)
1003         {
1004         }
CVDBStringValue(CVDBCursor & cursor,const char * param_name,const CTempString & param_value,const CVDBColumn & column)1005     CVDBStringValue(CVDBCursor& cursor,
1006                     const char* param_name, const CTempString& param_value,
1007                     const CVDBColumn& column)
1008         : CVDBValueFor<char>(cursor, param_name, param_value, column)
1009         {
1010         }
1011 
data(void) const1012     const char* data(void) const
1013         {
1014             return static_cast<const char*>(m_Data);
1015         }
1016 
operator CTempString(void) const1017     operator CTempString(void) const
1018         {
1019             return CTempString(data(), size());
1020         }
operator string(void) const1021     operator string(void) const
1022         {
1023             return Value();
1024         }
Value(void) const1025     string Value(void) const
1026         {
1027             return string(data(), size());
1028         }
1029 
operator *(void) const1030     CTempString operator*(void) const
1031         {
1032             return *this;
1033         }
1034 };
1035 
1036 
1037 typedef CVDBValueFor<uint16_t> CVDBUInt16Value;
1038 typedef CVDBValueFor<char> CVDBBytesValue;
1039 
1040 
1041 #ifndef NCBI_OS_MSWIN
1042 // Non-Windows paths are already POSIX
1043 inline
ConvertSysPathToPOSIX(const string & sys_path)1044 string CVPath::ConvertSysPathToPOSIX(const string& sys_path)
1045 {
1046     return sys_path;
1047 }
1048 
1049 
1050 // Non-Windows paths are already POSIX
1051 inline
ConvertAccOrSysPathToPOSIX(const string & acc_or_path)1052 string CVPath::ConvertAccOrSysPathToPOSIX(const string& acc_or_path)
1053 {
1054     return acc_or_path;
1055 }
1056 #endif
1057 
1058 
1059 END_SCOPE(objects)
1060 END_NCBI_SCOPE
1061 
1062 #endif // SRA__READER__SRA__VDBREAD__HPP
1063