//===--- HeaderMap.cpp - A file that acts like dir of symlinks ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the HeaderMap interface.
//
//===----------------------------------------------------------------------===//

#include "clang/Lex/HeaderMap.h"
#include "clang/Basic/FileManager.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/System/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cstdio>
using namespace clang;

//===----------------------------------------------------------------------===//
// Data Structures and Manifest Constants
//===----------------------------------------------------------------------===//

enum {
  HMAP_HeaderMagicNumber = ('h' << 24) | ('m' << 16) | ('a' << 8) | 'p',
  HMAP_HeaderVersion = 1,

  HMAP_EmptyBucketKey = 0
};

namespace clang {
struct HMapBucket {
  uint32_t Key;          // Offset (into strings) of key.

  uint32_t Prefix;     // Offset (into strings) of value prefix.
  uint32_t Suffix;     // Offset (into strings) of value suffix.
};

struct HMapHeader {
  uint32_t Magic;           // Magic word, also indicates byte order.
  uint16_t Version;         // Version number -- currently 1.
  uint16_t Reserved;        // Reserved for future use - zero for now.
  uint32_t StringsOffset;   // Offset to start of string pool.
  uint32_t NumEntries;      // Number of entries in the string table.
  uint32_t NumBuckets;      // Number of buckets (always a power of 2).
  uint32_t MaxValueLength;  // Length of longest result path (excluding nul).
  // An array of 'NumBuckets' HMapBucket objects follows this header.
  // Strings follow the buckets, at StringsOffset.
};
} // end namespace clang.

/// HashHMapKey - This is the 'well known' hash function required by the file
/// format, used to look up keys in the hash table.  The hash table uses simple
/// linear probing based on this function.
static inline unsigned HashHMapKey(const char *S, const char *End) {
  unsigned Result = 0;

  for (; S != End; S++)
    Result += tolower(*S) * 13;
  return Result;
}



//===----------------------------------------------------------------------===//
// Verification and Construction
//===----------------------------------------------------------------------===//

/// HeaderMap::Create - This attempts to load the specified file as a header
/// map.  If it doesn't look like a HeaderMap, it gives up and returns null.
/// If it looks like a HeaderMap but is obviously corrupted, it puts a reason
/// into the string error argument and returns null.
const HeaderMap *HeaderMap::Create(const FileEntry *FE) {
  // If the file is too small to be a header map, ignore it.
  unsigned FileSize = FE->getSize();
  if (FileSize <= sizeof(HMapHeader)) return 0;

  llvm::OwningPtr<const llvm::MemoryBuffer> FileBuffer(
    llvm::MemoryBuffer::getFile(FE->getName(), 0, FE->getSize()));
  if (FileBuffer == 0) return 0;  // Unreadable file?
  const char *FileStart = FileBuffer->getBufferStart();

  // We know the file is at least as big as the header, check it now.
  const HMapHeader *Header = reinterpret_cast<const HMapHeader*>(FileStart);

  // Sniff it to see if it's a headermap by checking the magic number and
  // version.
  bool NeedsByteSwap;
  if (Header->Magic == HMAP_HeaderMagicNumber &&
      Header->Version == HMAP_HeaderVersion)
    NeedsByteSwap = false;
  else if (Header->Magic == llvm::ByteSwap_32(HMAP_HeaderMagicNumber) &&
           Header->Version == llvm::ByteSwap_16(HMAP_HeaderVersion))
    NeedsByteSwap = true;  // Mixed endianness headermap.
  else
    return 0;  // Not a header map.

  if (Header->Reserved != 0) return 0;

  // Okay, everything looks good, create the header map.
  return new HeaderMap(FileBuffer.take(), NeedsByteSwap);
}

HeaderMap::~HeaderMap() {
  delete FileBuffer;
}

//===----------------------------------------------------------------------===//
//  Utility Methods
//===----------------------------------------------------------------------===//


/// getFileName - Return the filename of the headermap.
const char *HeaderMap::getFileName() const {
  return FileBuffer->getBufferIdentifier();
}

unsigned HeaderMap::getEndianAdjustedWord(unsigned X) const {
  if (!NeedsBSwap) return X;
  return llvm::ByteSwap_32(X);
}

/// getHeader - Return a reference to the file header, in unbyte-swapped form.
/// This method cannot fail.
const HMapHeader &HeaderMap::getHeader() const {
  // We know the file is at least as big as the header.  Return it.
  return *reinterpret_cast<const HMapHeader*>(FileBuffer->getBufferStart());
}

/// getBucket - Return the specified hash table bucket from the header map,
/// bswap'ing its fields as appropriate.  If the bucket number is not valid,
/// this return a bucket with an empty key (0).
HMapBucket HeaderMap::getBucket(unsigned BucketNo) const {
  HMapBucket Result;
  Result.Key = HMAP_EmptyBucketKey;

  const HMapBucket *BucketArray =
    reinterpret_cast<const HMapBucket*>(FileBuffer->getBufferStart() +
                                        sizeof(HMapHeader));

  const HMapBucket *BucketPtr = BucketArray+BucketNo;
  if ((char*)(BucketPtr+1) > FileBuffer->getBufferEnd()) {
    Result.Prefix = 0;
    Result.Suffix = 0;
    return Result;  // Invalid buffer, corrupt hmap.
  }

  // Otherwise, the bucket is valid.  Load the values, bswapping as needed.
  Result.Key    = getEndianAdjustedWord(BucketPtr->Key);
  Result.Prefix = getEndianAdjustedWord(BucketPtr->Prefix);
  Result.Suffix = getEndianAdjustedWord(BucketPtr->Suffix);
  return Result;
}

/// getString - Look up the specified string in the string table.  If the string
/// index is not valid, it returns an empty string.
const char *HeaderMap::getString(unsigned StrTabIdx) const {
  // Add the start of the string table to the idx.
  StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);

  // Check for invalid index.
  if (StrTabIdx >= FileBuffer->getBufferSize())
    return 0;

  // Otherwise, we have a valid pointer into the file.  Just return it.  We know
  // that the "string" can not overrun the end of the file, because the buffer
  // is nul terminated by virtue of being a MemoryBuffer.
  return FileBuffer->getBufferStart()+StrTabIdx;
}

/// StringsEqualWithoutCase - Compare the specified two strings for case-
/// insensitive equality, returning true if they are equal.  Both strings are
/// known to have the same length.
static bool StringsEqualWithoutCase(const char *S1, const char *S2,
                                    unsigned Len) {
  for (; Len; ++S1, ++S2, --Len)
    if (tolower(*S1) != tolower(*S2))
      return false;
  return true;
}

//===----------------------------------------------------------------------===//
// The Main Drivers
//===----------------------------------------------------------------------===//

/// dump - Print the contents of this headermap to stderr.
void HeaderMap::dump() const {
  const HMapHeader &Hdr = getHeader();
  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);

  fprintf(stderr, "Header Map %s:\n  %d buckets, %d entries\n",
          getFileName(), NumBuckets,
          getEndianAdjustedWord(Hdr.NumEntries));

  for (unsigned i = 0; i != NumBuckets; ++i) {
    HMapBucket B = getBucket(i);
    if (B.Key == HMAP_EmptyBucketKey) continue;

    const char *Key    = getString(B.Key);
    const char *Prefix = getString(B.Prefix);
    const char *Suffix = getString(B.Suffix);
    fprintf(stderr, "  %d. %s -> '%s' '%s'\n", i, Key, Prefix, Suffix);
  }
}

/// LookupFile - Check to see if the specified relative filename is located in
/// this HeaderMap.  If so, open it and return its FileEntry.
const FileEntry *HeaderMap::LookupFile(const char *FilenameStart,
                                       const char *FilenameEnd,
                                       FileManager &FM) const {
  const HMapHeader &Hdr = getHeader();
  unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);

  // If the number of buckets is not a power of two, the headermap is corrupt.
  // Don't probe infinitely.
  if (NumBuckets & (NumBuckets-1))
    return 0;

  // Linearly probe the hash table.
  for (unsigned Bucket = HashHMapKey(FilenameStart, FilenameEnd);; ++Bucket) {
    HMapBucket B = getBucket(Bucket & (NumBuckets-1));
    if (B.Key == HMAP_EmptyBucketKey) return 0; // Hash miss.

    // See if the key matches.  If not, probe on.
    const char *Key = getString(B.Key);
    unsigned BucketKeyLen = strlen(Key);
    if (BucketKeyLen != unsigned(FilenameEnd-FilenameStart))
      continue;

    // See if the actual strings equal.
    if (!StringsEqualWithoutCase(FilenameStart, Key, BucketKeyLen))
      continue;

    // If so, we have a match in the hash table.  Construct the destination
    // path.
    llvm::SmallString<1024> DestPath;
    DestPath += getString(B.Prefix);
    DestPath += getString(B.Suffix);
    return FM.getFile(DestPath.begin(), DestPath.end());
  }
}
