1591312c5SZachary Turner //===- DebugStringTableSubsection.cpp - CodeView String Table ---*- C++ -*-===//
2591312c5SZachary Turner //
3591312c5SZachary Turner //                     The LLVM Compiler Infrastructure
4591312c5SZachary Turner //
5591312c5SZachary Turner // This file is distributed under the University of Illinois Open Source
6591312c5SZachary Turner // License. See LICENSE.TXT for details.
7591312c5SZachary Turner //
8591312c5SZachary Turner //===----------------------------------------------------------------------===//
9591312c5SZachary Turner 
10591312c5SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
11591312c5SZachary Turner 
12591312c5SZachary Turner #include "llvm/Support/BinaryStream.h"
13591312c5SZachary Turner #include "llvm/Support/BinaryStreamReader.h"
14591312c5SZachary Turner #include "llvm/Support/BinaryStreamWriter.h"
15591312c5SZachary Turner 
16591312c5SZachary Turner using namespace llvm;
17591312c5SZachary Turner using namespace llvm::codeview;
18591312c5SZachary Turner 
19591312c5SZachary Turner DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
20591312c5SZachary Turner     : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
21591312c5SZachary Turner 
22591312c5SZachary Turner Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
23591312c5SZachary Turner   Stream = Contents;
24591312c5SZachary Turner   return Error::success();
25591312c5SZachary Turner }
261bf77620SZachary Turner Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {
27*deb39130SZachary Turner   return Reader.readStreamRef(Stream);
281bf77620SZachary Turner }
29591312c5SZachary Turner 
30591312c5SZachary Turner Expected<StringRef>
31591312c5SZachary Turner DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
32591312c5SZachary Turner   BinaryStreamReader Reader(Stream);
33591312c5SZachary Turner   Reader.setOffset(Offset);
34591312c5SZachary Turner   StringRef Result;
35591312c5SZachary Turner   if (auto EC = Reader.readCString(Result))
36591312c5SZachary Turner     return std::move(EC);
37591312c5SZachary Turner   return Result;
38591312c5SZachary Turner }
39591312c5SZachary Turner 
40591312c5SZachary Turner DebugStringTableSubsection::DebugStringTableSubsection()
41591312c5SZachary Turner     : DebugSubsection(DebugSubsectionKind::StringTable) {}
42591312c5SZachary Turner 
43591312c5SZachary Turner uint32_t DebugStringTableSubsection::insert(StringRef S) {
44591312c5SZachary Turner   auto P = Strings.insert({S, StringSize});
45591312c5SZachary Turner 
46591312c5SZachary Turner   // If a given string didn't exist in the string table, we want to increment
47591312c5SZachary Turner   // the string table size.
48591312c5SZachary Turner   if (P.second)
49591312c5SZachary Turner     StringSize += S.size() + 1; // +1 for '\0'
50591312c5SZachary Turner   return P.first->second;
51591312c5SZachary Turner }
52591312c5SZachary Turner 
53591312c5SZachary Turner uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
54591312c5SZachary Turner   return StringSize;
55591312c5SZachary Turner }
56591312c5SZachary Turner 
57591312c5SZachary Turner Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
58*deb39130SZachary Turner   uint32_t Begin = Writer.getOffset();
59*deb39130SZachary Turner   uint32_t End = Begin + StringSize;
60591312c5SZachary Turner 
61591312c5SZachary Turner   for (auto &Pair : Strings) {
62591312c5SZachary Turner     StringRef S = Pair.getKey();
63*deb39130SZachary Turner     uint32_t Offset = Begin + Pair.getValue();
64591312c5SZachary Turner     Writer.setOffset(Offset);
65591312c5SZachary Turner     if (auto EC = Writer.writeCString(S))
66591312c5SZachary Turner       return EC;
67*deb39130SZachary Turner     assert(Writer.getOffset() <= End);
68591312c5SZachary Turner   }
69591312c5SZachary Turner 
70*deb39130SZachary Turner   Writer.setOffset(End);
71591312c5SZachary Turner   return Error::success();
72591312c5SZachary Turner }
73591312c5SZachary Turner 
74591312c5SZachary Turner uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
75591312c5SZachary Turner 
76591312c5SZachary Turner uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
7792dcdda6SZachary Turner   auto Iter = Strings.find(S);
7892dcdda6SZachary Turner   assert(Iter != Strings.end());
7992dcdda6SZachary Turner   return Iter->second;
80591312c5SZachary Turner }
81