+// write header to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteHeader(void) {
+
+ size_t elementsWritten = 0;
+
+ // write magic number
+ elementsWritten += fwrite("BAI\1", sizeof(char), 4, m_parent->m_indexStream);
+
+ // store offset of beginning of data
+ m_dataBeginOffset = ftell64(m_parent->m_indexStream);
+
+ // return success/failure of write
+ return (elementsWritten == 4);
+}
+
+// write index data for all references to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteAllReferences(void) {
+
+ size_t elementsWritten = 0;
+
+ // write number of reference sequences
+ int32_t numReferenceSeqs = m_indexData.size();
+ if ( m_isBigEndian ) SwapEndian_32(numReferenceSeqs);
+ elementsWritten += fwrite(&numReferenceSeqs, sizeof(numReferenceSeqs), 1, m_parent->m_indexStream);
+
+ // iterate over reference sequences
+ bool refsOk = true;
+ BamStandardIndexData::const_iterator indexIter = m_indexData.begin();
+ BamStandardIndexData::const_iterator indexEnd = m_indexData.end();
+ for ( ; indexIter != indexEnd; ++ indexIter )
+ refsOk &= WriteReference( (*indexIter).second );
+
+ // return success/failure of write
+ return ( (elementsWritten == 1) && refsOk );
+}
+
+// write index data for bin to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteBin(const uint32_t& binId, const ChunkVector& chunks) {
+
+ size_t elementsWritten = 0;
+
+ // write BAM bin ID
+ uint32_t binKey = binId;
+ if ( m_isBigEndian ) SwapEndian_32(binKey);
+ elementsWritten += fwrite(&binKey, sizeof(binKey), 1, m_parent->m_indexStream);
+
+ // write chunks
+ bool chunksOk = WriteChunks(chunks);
+
+ // return success/failure of write
+ return ( (elementsWritten == 1) && chunksOk );
+}
+
+// write index data for bins to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteBins(const BamBinMap& bins) {
+
+ size_t elementsWritten = 0;
+
+ // write number of bins
+ int32_t binCount = bins.size();
+ if ( m_isBigEndian ) SwapEndian_32(binCount);
+ elementsWritten += fwrite(&binCount, sizeof(binCount), 1, m_parent->m_indexStream);
+
+ // iterate over bins
+ bool binsOk = true;
+ BamBinMap::const_iterator binIter = bins.begin();
+ BamBinMap::const_iterator binEnd = bins.end();
+ for ( ; binIter != binEnd; ++binIter )
+ binsOk &= WriteBin( (*binIter).first, (*binIter).second );
+
+ // return success/failure of write
+ return ( (elementsWritten == 1) && binsOk );
+}
+
+// write index data for chunk entry to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteChunk(const Chunk& chunk) {
+
+ size_t elementsWritten = 0;
+
+ // localize alignment chunk offsets
+ uint64_t start = chunk.Start;
+ uint64_t stop = chunk.Stop;
+
+ // swap endian-ness if necessary
+ if ( m_isBigEndian ) {
+ SwapEndian_64(start);
+ SwapEndian_64(stop);
+ }
+
+ // write to index file
+ elementsWritten += fwrite(&start, sizeof(start), 1, m_parent->m_indexStream);
+ elementsWritten += fwrite(&stop, sizeof(stop), 1, m_parent->m_indexStream);
+
+ // return success/failure of write
+ return ( elementsWritten == 2 );
+}
+
+// write index data for chunk entry to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteChunks(const ChunkVector& chunks) {
+
+ size_t elementsWritten = 0;
+
+ // write chunks
+ int32_t chunkCount = chunks.size();
+ if ( m_isBigEndian ) SwapEndian_32(chunkCount);
+ elementsWritten += fwrite(&chunkCount, sizeof(chunkCount), 1, m_parent->m_indexStream);
+
+ // iterate over chunks
+ bool chunksOk = true;
+ ChunkVector::const_iterator chunkIter = chunks.begin();
+ ChunkVector::const_iterator chunkEnd = chunks.end();
+ for ( ; chunkIter != chunkEnd; ++chunkIter )
+ chunksOk &= WriteChunk( (*chunkIter) );
+
+ // return success/failure of write
+ return ( (elementsWritten == 1) && chunksOk );
+}
+
+// write index data for linear offsets entry to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteLinearOffsets(const LinearOffsetVector& offsets) {
+
+ size_t elementsWritten = 0;
+
+ // write number of linear offsets
+ int32_t offsetCount = offsets.size();
+ if ( m_isBigEndian ) SwapEndian_32(offsetCount);
+ elementsWritten += fwrite(&offsetCount, sizeof(offsetCount), 1, m_parent->m_indexStream);
+
+ // iterate over linear offsets
+ LinearOffsetVector::const_iterator offsetIter = offsets.begin();
+ LinearOffsetVector::const_iterator offsetEnd = offsets.end();
+ for ( ; offsetIter != offsetEnd; ++offsetIter ) {
+
+ // write linear offset
+ uint64_t linearOffset = (*offsetIter);
+ if ( m_isBigEndian ) SwapEndian_64(linearOffset);
+ elementsWritten += fwrite(&linearOffset, sizeof(linearOffset), 1, m_parent->m_indexStream);
+ }
+
+ // return success/failure of write
+ return ( elementsWritten == (size_t)(offsetCount + 1) );
+}
+
+// write index data for a single reference to new index file
+bool BamStandardIndex::BamStandardIndexPrivate::WriteReference(const ReferenceIndex& refEntry) {
+ bool refOk = true;
+ refOk &= WriteBins(refEntry.Bins);
+ refOk &= WriteLinearOffsets(refEntry.Offsets);
+ return refOk;
+}
+