//***************************************************************************
// This source code is copyrighted 2002 by Google Inc.  All rights
// reserved.  You are given a limited license to use this source code for
// purposes of participating in the Google programming contest.  If you
// choose to use or distribute the source code for any other purpose, you
// must either (1) first obtain written approval from Google, or (2)
// prominently display the foregoing copyright notice and the following
// warranty and liability disclaimer on each copy used or distributed.
// 
// The source code and repository (the "Software") is provided "AS IS",
// with no warranty, express or implied, including but not limited to the
// implied warranties of merchantability and fitness for a particular
// use.  In no event shall Google Inc. be liable for any damages, direct
// or indirect, even if advised of the possibility of such damages.
//***************************************************************************


// The ReposReader class reads basic data types out of a pre-parsed
// format repository file (provided as a std::ifstream).  It knows how
// to decode char*, signed and unsigned integers, and bytes, and
// handles any required buffering while reading from the file.

#ifndef REPOS_READER_H
#define REPOS_READER_H

#include <iostream>
#include <string>
#include "goo-document.h"
#include "goo-basictypes.h"
#include "goo-netutil.h"


class ReposReader {
 public:
  // Note: ReposReader does not take ownership of "repos".
  ReposReader(std::istream* repos, const string& repos_name);
  virtual ~ReposReader(void) { };

  // The following two routines read characters into an internal buffer
  // and return a pointer to the buffer. The buffer contents may be
  // modified on subsequent calls so copy it if you need it across
  // multiple calls. ReadCharStar returns the number of characters
  // read, while ReadCharsOnly takes the number to read as an argument.
  // We guarantee that the buffer is at least 1 byte bigger than the number
  // of chars returned (so the caller can add a '\0' if desired).
  const char* ReadCharStar(int* len);
  const char* ReadCharsOnly(int numchars);

  uint32 ReadFixedUint32();
  uint32 ReadVarUint32();
  unsigned char ReadByte();
  int ReadInt();
  bool AtEnd() const;
  int cur_pos() const { return cur_pos_; }
  const string& repos_name() const { return repos_name_; }
  // Report a parsing error and exit. Gives some info about the
  // current position in the repository.
  void ParseError(const string& errmsg);

 private:
  void RefillBuf();
  void ReallocCharsBuf(int size);

  static const int kDecodeBufSize = 1024;
  static const int kReadBufSize = 10000;

  std::istream* repos_;
  const string repos_name_;
  char decode_buf_[kDecodeBufSize];
  int decode_buf_len_;  // number of chars currently in decode_buf_
  Decoder decoder_;
  int cur_pos_;

  char* chars_buf_;      // buffer for ReadCharStar and ReadCharsOnly
  int chars_buf_len_;    // current size of chars_buf_
};

#endif

