// fileread.cc -- read files for gold

#include "gold.h"

#include <cassert>
#include <cstring>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>

#include "options.h"
#include "dirsearch.h"
#include "fileread.h"

namespace gold
{

// Class File_read::View.

File_read::View::~View()
{
  assert(!this->is_locked());
  delete[] this->data_;
}

void
File_read::View::lock()
{
  ++this->lock_count_;
}

void
File_read::View::unlock()
{
  assert(this->lock_count_ > 0);
  --this->lock_count_;
}

bool
File_read::View::is_locked()
{
  return this->lock_count_ > 0;
}

// Class File_read.

// The File_read class is designed to support file descriptor caching,
// but this is not currently implemented.

File_read::~File_read()
{
  assert(this->lock_count_ == 0);
  if (this->descriptor_ >= 0)
    {
      if (close(this->descriptor_) < 0)
	fprintf(stderr, _("%s: warning: close(%s) failed: %s"),
		program_name, this->name_.c_str(), strerror(errno));
      this->descriptor_ = -1;
    }
  this->name_.clear();
  this->clear_views(true);
}

bool
File_read::open(const std::string& name)
{
  assert(this->lock_count_ == 0
	 && this->descriptor_ < 0
	 && this->name_.empty());
  this->name_ = name;
  this->descriptor_ = ::open(this->name_.c_str(), O_RDONLY);
  ++this->lock_count_;
  return this->descriptor_ >= 0;
}

int
File_read::get_descriptor()
{
  assert(this->lock_count_ > 0);
  return this->descriptor_;
}

void
File_read::lock()
{
  ++this->lock_count_;
}

void
File_read::unlock()
{
  assert(this->lock_count_ > 0);
  --this->lock_count_;
}

bool
File_read::is_locked()
{
  return this->lock_count_ > 0;
}

// See if we have a view which covers the file starting at START for
// SIZE bytes.  Return a pointer to the View if found, NULL if not.

inline File_read::View*
File_read::find_view(off_t start, off_t size)
{
  off_t page = File_read::page_offset(start);
  Views::iterator p = this->views_.find(page);
  if (p == this->views_.end())
    return NULL;
  if (p->second->size() - (start - page) < size)
    return NULL;
  return p->second;
}

// Read data from the file.  Return the number of bytes read.  If
// PBYTES is not NULL, store the number of bytes in *PBYTES, otherwise
// require that we read exactly the number of bytes requested.

off_t
File_read::do_read(off_t start, off_t size, void* p, off_t* pbytes)
{
  assert(this->lock_count_ > 0);
  int o = this->descriptor_;

  if (lseek(o, start, SEEK_SET) < 0)
    {
      fprintf(stderr, _("%s: %s: lseek to %lld failed: %s"),
	      program_name, this->filename().c_str(),
	      static_cast<long long>(start),
	      strerror(errno));
      gold_exit(false);
    }

  off_t bytes = ::read(o, p, size);
  if (bytes < 0)
    {
      fprintf(stderr, _("%s: %s: read failed: %s\n"),
	      program_name, this->filename().c_str(), strerror(errno));
      gold_exit(false);
    }

  if (pbytes != NULL)
    *pbytes = bytes;
  else if (bytes != size)
    {
      fprintf(stderr,
	      _("%s: %s: file too short: read only %lld of %lld "
		"bytes at %lld\n"),
	      program_name, this->filename().c_str(),
	      static_cast<long long>(bytes),
	      static_cast<long long>(size),
	      static_cast<long long>(start));
      gold_exit(false);
    }

  return bytes;
}

void
File_read::read(off_t start, off_t size, void* p, off_t* pbytes)
{
  assert(this->lock_count_ > 0);

  File_read::View* pv = this->find_view(start, size);
  if (pv != NULL)
    {
      memcpy(p, pv->data() + (start - pv->start()), size);
      if (pbytes != NULL)
	*pbytes = size;
      return;
    }

  this->do_read(start, size, p, pbytes);
}

// Find an existing view or make a new one.

File_read::View*
File_read::find_or_make_view(off_t start, off_t size, off_t* pbytes)
{
  assert(this->lock_count_ > 0);

  off_t poff = File_read::page_offset(start);

  File_read::View* const vnull = NULL;
  std::pair<Views::iterator, bool> ins =
    this->views_.insert(std::make_pair(poff, vnull));

  if (!ins.second)
    {
      // There was an existing view at this offset.
      File_read::View* v = ins.first->second;
      if (v->size() - (start - v->start()) >= size)
	{
	  if (pbytes != NULL)
	    *pbytes = size;
	  return v;
	}

      // This view is not large enough.
      this->saved_views_.push_back(v);
    }

  // We need to read data from the file.

  off_t psize = File_read::pages(size + (start - poff));
  unsigned char* p = new unsigned char[psize];

  off_t got_bytes;
  off_t bytes = this->do_read(poff, psize, p, &got_bytes);

  File_read::View* v = new File_read::View(poff, bytes, p);

  ins.first->second = v;

  if (bytes - (start - poff) >= size)
    {
      if (pbytes != NULL)
	*pbytes = size;
      return v;
    }

  if (pbytes != NULL)
    {
      *pbytes = bytes - (start - poff);
      return v;
    }

  fprintf(stderr,
	  _("%s: %s: file too short: read only %lld of %lld bytes at %lld\n"),
	  program_name, this->filename().c_str(),
	  static_cast<long long>(bytes - (start - poff)),
	  static_cast<long long>(size),
	  static_cast<long long>(start));
  gold_exit(false);
}

// This implementation of get_view just reads into a memory buffer,
// which we store on view_list_.  At some point we should support
// mmap.

const unsigned char*
File_read::get_view(off_t start, off_t size, off_t* pbytes)
{
  assert(this->lock_count_ > 0);
  File_read::View* pv = this->find_or_make_view(start, size, pbytes);
  return pv->data() + (start - pv->start());
}

File_view*
File_read::get_lasting_view(off_t start, off_t size, off_t* pbytes)
{
  assert(this->lock_count_ > 0);
  File_read::View* pv = this->find_or_make_view(start, size, pbytes);
  pv->lock();
  return new File_view(*this, pv, pv->data() + (start - pv->start()));
}

// Remove all the file views.

void
File_read::clear_views(bool destroying)
{
  for (Views::iterator p = this->views_.begin();
       p != this->views_.end();
       ++p)
    {
      if (!p->second->is_locked())
	delete p->second;
      else
	{
	  assert(!destroying);
	  this->saved_views_.push_back(p->second);
	}
    }
  this->views_.clear();

  Saved_views::iterator p = this->saved_views_.begin();
  while (p != this->saved_views_.end())
    {
      if (!(*p)->is_locked())
	{
	  delete *p;
	  p = this->saved_views_.erase(p);
	}
      else
	{
	  assert(!destroying);
	  ++p;
	}
    }
}

// Class File_view.

File_view::~File_view()
{
  assert(this->file_.is_locked());
  this->view_->unlock();
}

// Class Input_file.

void
Input_file::open(const General_options& options, const Dirsearch& dirpath)
{
  std::string name;
  if (!this->input_argument_.is_lib())
    name = this->input_argument_.name();
  else
    {
      std::string n1("lib");
      n1 += this->input_argument_.name();
      std::string n2;
      if (options.is_static())
	n1 += ".a";
      else
	{
	  n2 = n1 + ".a";
	  n1 += ".so";
	}
      name = dirpath.find(n1, n2);
      if (name.empty())
	{
	  fprintf(stderr, _("%s: cannot find %s\n"), program_name,
		  this->input_argument_.name());
	  gold_exit(false);
	}
    }

  if (!this->file_.open(name))
    {
      fprintf(stderr, _("%s: cannot open %s: %s\n"), program_name,
	      name.c_str(), strerror(errno));
      gold_exit(false);
    }
}

} // End namespace gold.
