 /**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
****************************************************************************
*
* File:         NAStringDef.cpp (previously under /common)
* Description:
*
* Created:      5/6/98
* Language:     C++
*
*
*
****************************************************************************
*/

#include "Platform.h"


#include "NAAssert.h"

#include <iostream>

// -----------------------------------------------------------------------
//
// class NAString : derived from the source for FaceBook FBString
//                  --> adapted to take a NAMemory* in every ctor
//
// -----------------------------------------------------------------------

#include "NAStringDef.h"
#include "NAMemory.h"
#include "str.h"
#include <stdarg.h>

#include "str.h"
#include <fstream>
using namespace std;

// we're using the multithread-safe versions here
#define MULTITHREAD_LOCK
#include <ctype.h>
#include <stdlib.h>

const UInt32 NA_HASH_SHIFT = 5;

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                              NAString                               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


NAString::NAString (NAMemory *h)                
  :fbstring_((h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
{}

NAString::NAString (NASize_T ic, NAMemory *h) 
  :fbstring_((h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
{
  fbstring_.reserve(ic);
}

NAString::NAString (const NASubString & substr, NAMemory *h)
  :fbstring_(substr.startData(), substr.length(), (h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h) {}


NAString::NAString (const NAString & S, NAMemory *h)
  :fbstring_(S.fbstring_, (h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)      
{
  // if we're supposed to be on the same heap, then we can share
}

NAString::NAString (const char * cs, NAMemory *h)
  :fbstring_(cs, (h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)        
{
  assert(cs!=nanil);
}

NAString::NAString (const char * cs, size_t N, NAMemory *h)
  :fbstring_(cs, N, (h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h) 
{
  assert(cs!=nanil);
} 

NAString::NAString (char c, size_t N, NAMemory *h)
  :fbstring_(N, c, (h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)    
{}

// these three ctors are all the same
NAString::NAString(char c, NAMemory *h)
  :fbstring_((h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
{
  fbstring_.push_back(c);
}

NAString::NAString(unsigned char c, NAMemory *h)
  :fbstring_((h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
{
  fbstring_.push_back(char(c));
}

NAString::NAString(signed char c, NAMemory *h)
  :fbstring_((h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
{
  fbstring_.push_back(char(c));
}

NAString::NAString(const FBString & fbs, NAMemory *h)
  :fbstring_(fbs, (h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
{}

NAString::~NAString()
{}

NAString&
NAString::operator=(const char * cs)
{
  fbstring_ = cs;
  return *this;
}

NAString&
NAString::operator=(const NAString& str)
{
  fbstring_ = str.fbstring_;
  return *this;
}

/********************** Member Functions *************************/

NAString&
NAString::append(const char c, size_t rep)
{
  fbstring_.append(rep, c);
  return *this;
}

// Change the string capacity, returning the new capacity
size_t
NAString::capacity(size_t nc)
{
  if (nc > length() && nc != capacity())
    clone(nc);

  assert(capacity() >= length());
  return capacity();
}

// Erase the contents of a string
void
NAString::clear(void)
{
  fbstring_.clear();
}

// String comparisons
Int32
NAString::compareTo(const char* cs2, caseCompare cmp) const
{
  assert(cs2!=nanil);
  const char* cs1 = data();
  size_t len = length();
  size_t i = 0;
  if (cmp == exact) {
    for (; cs2[i]; ++i) {
      if (i == len) return -1;
      if (cs1[i] != cs2[i]) return ((cs1[i] > cs2[i]) ? 1 : -1);
    }
  } else {                  // ignore case
    for (; cs2[i]; ++i) {
      if (i == len) return -1;
      char c1 = tolower((unsigned char)cs1[i]);
      char c2 = tolower((unsigned char)cs2[i]);
      if (c1 != c2) return ((c1 > c2)? 1 : -1);
    }
  }
  return (i < len) ? 1 : 0;
}

Int32
NAString::compareTo(const NAString& str, caseCompare cmp) const
{
  const char* s1 = data();
  const char* s2 = str.data();
  size_t len = str.length();
  if (length() < len) len = length();
  if (cmp == exact) {
    return fbstring_.compare(str.fbstring_);
  } else {
    size_t i = 0;
    for (; i < len; ++i) {
      char c1 = tolower((unsigned char)s1[i]);
      char c2 = tolower((unsigned char)s2[i]);
      if (c1 != c2) return ((c1 > c2)? 1 : -1);
    }
  }
  // strings are equal up to the length of the shorter one.
  if (length() == str.length()) return 0;
  return (length() > str.length())? 1 : -1;
}


NAString
NAString::copy() const
{
  NAString temp(*this);	// Has increased reference count
  temp.clone();			// Distinct copy
  return temp;
}

int
NAString::extract(int begin, int end, NAString & target) const
{
  if(end >= length() || begin < 0 ||end < begin) 
      return -1;

  for(int i = begin; i <= end; i++)
      target.append((*this)[i]);

  return end - begin;
}


UInt32 
NAString::hashFoldCase() const
{
  UInt32 hv = (UInt32)length();    // Mix in the string length.
  UInt32 i  = hv;
  const unsigned char* p = (const unsigned char*) data();
  while (i--) {
    mash(hv, toupper(*p));
    ++p;
  }
  return hv;
}

void
NAString::mash(UInt32& hash, UInt32 chars) const
{
  hash = (chars ^
       ((hash << NA_HASH_SHIFT) |
        (hash >> (BITSPERBYTE*sizeof(UInt32) - NA_HASH_SHIFT))));
}

/*
 * Return a case-sensitive hash value.
 */
UInt32
NAString::hash() const
{
  UInt32 hv       = (UInt32)length(); // Mix in the string length.
  UInt32 i        = length()*sizeof(char)/sizeof(UInt32);
  const UInt32* p = (const UInt32*)data();
  {
    while (i--)
      mash(hv, *p++);			// XOR in the characters.
  }
  // XOR in any remaining characters:
  if ((i = length()*sizeof(char)%sizeof(UInt32)) != 0) {
    UInt32 h = 0;
    const char* c = (const char*)p;
    while (i--) 
      h = ((h << BITSPERBYTE*sizeof(char)) | *c++);
    mash(hv, h);
  }
  return hv;
}

UInt32
NAString::hash(caseCompare cmp) const
{
  return (cmp==exact) ? hash() : hashFoldCase();
}


static Int32
rwMemiEqual(const char* p, const char* q, size_t N)
{
  while (N--)
  {
    if (tolower((unsigned char)*p) != tolower((unsigned char)*q))
      return FALSE;
    p++; q++;
  }
  return TRUE;
}

// Pattern Matching:

size_t
NAString::index(const char* pattern,	// Pattern to search for
		 size_t plen,		// Length of pattern
		 size_t startIndex,	// Starting index from which to start
		 caseCompare cmp) const	// What type of case-comparison
{
  assert(pattern!=nanil);
  if (cmp == exact) {
    return fbstring_.find(pattern, startIndex, plen);
  } else {
    FBString tmp = fbstring_;
    register char* p = tmp.begin();
    register size_t N = tmp.length();
    while ( N-- ) { *p = tolower((unsigned char)*p); p++;}
    FBString pat(pattern);
    p = pat.begin();
    N = pat.length();
    while ( N-- ) { *p = tolower((unsigned char)*p); p++;}
    return tmp.find(pat.data(), startIndex, pat.length());
  }
}

// Prepend characters to self:
NAString&
NAString::prepend(char c, size_t rep)
{
  fbstring_.insert(0, rep, c);
  return *this;
}

// Remove at most n1 characters from self beginning at pos,
// and replace them with the first n2 characters of cs.
NAString&
NAString::replace(size_t pos, size_t n1, const char* cs, size_t n2)
{
  fbstring_.replace(pos, n1, cs, n2);
  return *this;
}

void NAString::adjustMemory(size_t tot)
{
  if (capacity() >= tot) return;
  fbstring_.reserve(tot);
}

// Truncate or add blanks as necessary
void
NAString::resize(size_t N)
{
  fbstring_.resize(N, ' ');			// Shrank; truncate the string
}

NAList<NAString> & NAString::split(char delim, NAList<NAString> & elems)
{
  int begin = 0;
  int end = 0;
  elems.clear();
  end = fbstring_.find_first_of(delim, begin);
  //For string like "w1|w2|w3|", devided by '|' we get 4 words
  //"w1", "w2", "w3", ""
  while(end >= begin)
  {
     NAString word(fbstring_.data() + begin,  end - begin);
     elems.insert(word);
     begin = end + 1;
     end = fbstring_.find_first_of(delim, begin);
  }
  if(fbstring_.size() > 0)
  {
    NAString end_word(fbstring_.data()+begin, fbstring_.size()-begin);
    elems.insert(end_word);
  }
  
  return elems;
}

Int32 NAString::readFile(ifstream& in) // Read to EOF or null character.
{
    char c;
    Int32 char_count = 0;
    fbstring_ = "";
    c = in.get();
    while(c != '\0' && c!=EOF)
    {
        fbstring_.append(1, c);
        c = in.get();
        char_count++;
    }
    return char_count;
}

Int32 NAString::readLine(ifstream& in)   // Read to EOF or newline.
{
    return readToDelim(in, '\n');
}

Int32 NAString::readToDelim(ifstream& in, char delim) // Read to EOF or delimitor.
{
    char c;
    Int32 char_count = 0;
    fbstring_ = "";
    c = in.get();
    while(c != '\0' && c!=delim && c!=EOF)
    {
        fbstring_.append(1, c);
        c = in.get();
        char_count++;
    }
    return char_count;
}

//This static function calculates and allocates buffer for the printf-like formatted string,
//and the formatted string is copied to the buffer.
char* NAString::buildBuffer(const char* formatTemplate, va_list args)
{
  // calculate needed bytes to allocate memory from system heap.
  int bufferSize = 20049;
  int msgSize = 0;
  //buffer is managed by this static function
  //the allocated memory is shared by all NAString objects.
  static THREAD_P char *buffer = NULL;
  va_list args2;
  va_copy(args2, args);
  bool secondTry = false;
  if (buffer == NULL)
      buffer = new char[bufferSize];
  // For messages shorter than the initial 20K limit, a single pass through
  // the loop will suffice.
  // For longer messages, 2 passes will do it. The 2nd pass uses a buffer of the
  // size returned by the call to vsnprintf. If a second pass is necessary, we
  // pass the copy of the va_list we made above, because the first call changes
  // the state of the va_list, and can cause a crash if reused.
  while(1)
  {
      msgSize = vsnprintf(buffer, bufferSize, formatTemplate, secondTry ? args2 : args);
      if ( msgSize < 0 ){
          //there is error, try second time
          if(!secondTry){
              secondTry = TRUE;
              continue;
          }
          else
            return NULL;//error second time
      }
      else if(msgSize < bufferSize) {
          // Buffer is large enough - we're good.
          break; 
      }
      else { 
          // Buffer is too small, reallocate it and go through the loop again.
          bufferSize = msgSize + 1; // Use correct size now.
          delete [] buffer;
          buffer = new char[bufferSize];
          secondTry = true;
      }
  }
  va_end(args2);
  return buffer;
}

NABoolean NAString::format(const char* formatTemplate...)
{
  NABoolean retcode;
  va_list args ;
  va_start(args, formatTemplate);

  char * buffer = buildBuffer(formatTemplate, args);
  if(buffer) {
    fbstring_ = buffer;
    retcode = TRUE;
  }
  else {
    fbstring_ = "";
    retcode = FALSE;
  }  
  va_end(args);
  return retcode;
}

// Return a substring of self stripped at beginning and/or end

NASubString NAString::strip (NAString::stripType st, char c)
{
  size_t start = 0;		// Index of first character
  size_t end = length();	// One beyond last character
  const char* direct = data();	// Avoid a dereference w dumb compiler

  assert((Int32)st != 0);
  if (st & leading)
    while (start < end && direct[start] == c)
      ++start;
  if (st & trailing)
    while (start < end && direct[end-1] == c)
      --end;
  if (end == start) start = end = NA_NPOS;  // make the null substring
  return NASubString(*this, start, end-start);
}


NASubString NAString::strip(NAString::stripType st, char c) const
{
  // Just use the "non-const" version, adjusting the return type:
  return ((NAString*)this)->strip(st,c);
}


// Change self to lower-case
void
NAString::toLower()
{
  cow();
  register size_t N = length();
  register char* p = fbstring_.begin();
  while ( N-- ) { *p = tolower((unsigned char)*p); p++;}
}

// Change self to upper case
void
NAString::toUpper()
{
  cow();
  register size_t N = length();
  register char* p = fbstring_.begin();
  while ( N-- ) { *p = toupper((unsigned char)*p); p++;}
}

// Change self to upper case
void
NAString::toUpper8859_1()
{
  cow();
  register size_t N = length();
  register unsigned char* p = (unsigned char *)(fbstring_.begin());
  while ( N-- ) 
  { 
    if ((isLower8859_1((unsigned char) *p)) &&
        (*p != 0xff) &&    // small y with diaeresis has no upcase equiv in 8859-1
        (*p != 0xdf))      // small german sharp s has no upcase euqiv in 8859-1
    {
      *p = *p - 32; // convert to uppercase equivalent
    }
    p++;
  }
}

char&
NAString::operator[](size_t i)
{
   assertElement(i); 
   cow();
   return fbstring_[i];
}

// Check to make a string index is in range
void
NAString::assertElement(size_t i) const
{
  if (i>=length() ) // NA_NPOS is > any legal length()
  {
    assert (i < length()) ;                                     
  }
}

/********************** Protected functions ***********************/

// Special constructor to initialize with the concatenation of a1 and a2:
NAString::NAString(const char* a1, size_t N1, const char* a2, size_t N2, NAMemory *h )
  //:fbstring_(a1, N1+N2, (h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
  :fbstring_((h == NASTRING_UNINIT_HEAP_PTR) ? this->defaultHeapPtr() : h)
{
  fbstring_ = FBString(a1, N1) + FBString(a2, N2);
  //fbstring_.replace(N1, N2, a2, N2);
}

void NAString::clobber(size_t nc)
{
  fbstring_.clear();
  fbstring_.reserve(nc);
}

// Make self a distinct copy; 
// preserve previous contents
void
NAString::clone()
{
  //indirectly call mutable_data()
  //to make self distinct
  fbstring_.begin();
}

// Make self a distinct copy with capacity of at least nc;
// preserve previous contents
void
NAString::clone(size_t nc)
{
  fbstring_.reserve(nc);
}

/****************** Related global functions ***********************/

NABoolean 
operator==(const NAString& s1, const char* s2)
{
  const char* data = s1.data();
  size_t len = s1.length();
  size_t i;
  for (i = 0; s2[i]; ++i)
    if (data[i] != s2[i] || i == len) return FALSE;
  return (i == len);
}

// Return a lower-case version of str:
NAString 
toLower(const NAString& str)
{
  register size_t N = str.length();
  NAString temp((char)0, N);
  register const char* uc = str.data();
  register       char* lc = (char*)temp.data();
  // Guard against tolower() being a macro:
  while( N-- ) { *lc++ = tolower((unsigned char)*uc); uc++; }
  return temp;
}

// Return an upper-case version of str:
NAString 
toUpper(const NAString& str)
{
  register size_t N = str.length();
  NAString temp((char)0, N);
  register const char* uc = str.data();
  register       char* lc = (char*)temp.data();
  // Guard against toupper() being a macro:
  while( N-- ) { *lc++ = toupper((unsigned char)*uc); uc++; }
  return temp;
}

NAString 
operator+(const NAString& s, const char* cs)
{
  // Use the special concatenation constructor:
  return NAString(s.data(), s.length(), cs, strlen(cs), s.heap());
}            

NAString 
operator+(const NAString& s, const char c)
{
  // Use the special concatenation constructor:
  NAString temp(c);
  return NAString(s.data(), s.length(), temp.data(), temp.length(), s.heap());
}            

NAString 
operator+(const char* cs, const NAString& s)
{
  // Use the special concatenation constructor:
  return NAString(cs, strlen(cs), s.data(), s.length(), s.heap());
}

NAString 
operator+(const NAString& s1, const NAString& s2)
{
  // Use the special concatenation constructor:
  return NAString(s1.data(), s1.length(), s2.data(), s2.length(), s1.heap());
}

/* static */ UInt32
NAString::hash(const NAString& str)
{
  return str.hash();
}

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                             NASubString                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

/*
 * A zero lengthed substring is legal.  It can start
 * at any character.  It is considered to be "pointing"
 * to just before the character.
 *
 * A "null" substring is a zero lengthed substring that
 * starts with the nonsense index NA_NPOS.  It can
 * be detected with the member function isNull().
 */

// Private constructor 
NASubString::NASubString(const NAString & str, size_t start, size_t nextent)
: str_((NAString*)&str),
  begin_(start),
  extent_(nextent)
{
#ifndef NDEBUG
  size_t N = str.length();

  // Allow zero lengthed and null substrings:
  if ((start==NA_NPOS && nextent!=0) || (start!=NA_NPOS && start+nextent>N))
    subStringError(N, start, nextent);
#endif
}

// Sub-string operator
NASubString 
NAString::operator()(size_t start, size_t len) 
{
  return NASubString(*this, start, len);
}

/*
 * Returns a substring matching "pattern", or the null substring 
 * if there is no such match.  It would be nice if this could be yet another 
 * overloaded version of operator(), but this would result in a type
 * conversion ambiguity with operator(size_t, size_t). 
 */
NASubString
NAString::subString(const char* pattern, size_t startIndex, caseCompare cmp)
{
  assert(pattern!=nanil);
  size_t len = strlen(pattern);
  size_t i = index(pattern, len, startIndex, cmp);
  return NASubString(*this, i, i == NA_NPOS ? 0 : len);
}
char&
NASubString::operator[](size_t i)
{
   assertElement(i); 
   str_->cow();
   return (*str_)[begin_+i];
}

char&
NASubString::operator()(size_t i)
{ 
#ifndef NDEBUG
   assertElement(i);
#endif
   str_->cow();
   return (*str_)[begin_+i];
}

NASubString
NAString::operator()(size_t start, size_t len) const
{
  return NASubString(*this, start, len);
}

NASubString
NAString::subString(const char* pattern, size_t startIndex, caseCompare cmp) const
{
  assert(pattern!=nanil);
  size_t len = strlen(pattern);
  size_t i = index(pattern, len, startIndex, cmp);
  return NASubString(*this, i, i == NA_NPOS ? 0 : len);
}

NASubString&
NASubString::operator=(const NAString& str) 
{
  if( !isNull() ) {
    size_t len = str.length();
    str_->replace(begin_, extent_, str.data(), len);
    extent_ = len;
  }
  return *this;
}

NASubString&
NASubString::operator=(const NASubString& s) 
{
  if( !isNull() ) {
    str_->replace(begin_, extent_, s.data(), s.length());
    extent_ = s.length();
  }
  return *this;
}

NASubString&
NASubString::operator=(const char* cs)
{
  if (!isNull() ) {
    size_t len = strlen(cs);
    str_->replace(begin_, extent_, cs, len);
    extent_ = len;
  }
  return *this;
}

NABoolean 
operator==(const NASubString& ss, const char* cs)
{
  assert(cs!=nanil);

  if ( ss.isNull() ) return *cs =='\0'; // Two null strings compare equal

  assert(ss.begin_+ss.extent_<=ss.str_->length());

  const char* data = ss.str_->data() + ss.begin_;
  size_t i;
  for (i = 0; cs[i]; ++i)
    if (cs[i] != data[i] || i == ss.extent_) return FALSE;
  return (i == ss.extent_);
}

NABoolean 
operator==(const NASubString& ss, const NAString& s)
{
  if (ss.isNull()) return s.isNull(); // Two null strings compare equal.
  if (ss.extent_ != s.length()) return FALSE;
  return !memcmp(ss.str_->data() + ss.begin_, s.data(), ss.extent_);
}

NABoolean 
operator==(const NASubString& s1, const NASubString& s2)
{
  if (s1.isNull()) return s2.isNull();
  if (s1.extent_ != s2.extent_) return FALSE;
  return !memcmp(s1.str_->data()+s1.begin_, s2.str_->data()+s2.begin_, s1.extent_);
}

// Convert self to lower-case
void
NASubString::toLower()
{
  if(!isNull())
  {				// Ignore null substrings
     str_->cow();
     register char* p = (char*)(str_->data() + begin_); // Cast away constness
     size_t N = extent_;
     while( N-- ) { *p = tolower((unsigned char)*p); p++;}
  }
}

// Convert self to upper-case
void
NASubString::toUpper()
{
  if(!isNull())
  {				// Ignore null substrings
     str_->cow();
     register char* p = (char*)(str_->data() + begin_); // Cast away constness
     size_t N = extent_;
     while( N-- ) { *p = toupper((unsigned char)*p); p++;}
  }
}

void
NASubString::subStringError(size_t sr, size_t start, size_t n) const
{
  assert (FALSE) ; 
}

void
NASubString::assertElement(size_t i) const
{
  if (i>=length() ) // NA_NPOS is > any legal length()
  {
    assert ( i < length() ) ;
  }
}


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                           LOCALE RELATED                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

NABoolean
NAString::isAscii() const
{
  const char* cp = data();
  for (size_t i = 0; i < length(); ++i)
    if (cp[i] & ~0x7F)
      return FALSE;
  return TRUE;
}

#ifndef RW_NO_LOCALE

NAString 
strXForm(const NAString& cstr)
{
  // Get the size required to transform the string;
  // cast to "char*" necessary for Sun cfront:
  size_t N = ::strxfrm(NULL, (char*)cstr.data(), 0) + 1;

  NAString temp((char)0, N);

  // Return null string in case of failure:
  if ( ::strxfrm((char*)temp.data(), (char*)cstr.data(), N) >= N )
    return NAString();

  return temp;
}

size_t
NAString::mbLength() const 
{
  const char* cp = data();
  size_t i = 0;
  size_t len = 0;
  mblen((const char*)0, MB_CUR_MAX);  // clear static state (bleah!)
  while (i < length() && cp[i]) {
    Int32 l = mblen(cp+i, MB_CUR_MAX);
    if (l <= 0) return NA_NPOS;
    i += l;
    ++len;
  }
  if (i > length()) return NA_NPOS; // incomplete last char
  return len;
}

#endif /* RW_NO_LOCALE */

/*
 * Warning: certain implementations of iostreams have been
 * found to reset the stream width after ostream::write() is called.
 * In the function below, the characters are output directly through
 * the streambuf.
 */

ostream& 
operator<<(ostream& os, const NAString& s)
{
  // ANSI replaced opfx/osfx to implicit calls in the ctor/dtor 
  // of the sentry class
  if (!os.good()) return os;

  ostream::sentry opfx(os);
  if(opfx)
  {
    size_t len = s.length();
    size_t wid = os.width();
    wid = (len < wid) ? wid - len : 0;
    Lng32 flags = os.flags();
    os.width(wid);
    if (wid && !(flags & ios::left))
      os << "";  // let the ostream fill
    os.rdbuf()->sputn((char*)s.data(), s.length());
    if (wid && (flags & ios::left))
      os << "";  // let the ostream fill


  // no need to destroy sentry: it will go out of scope.
  }
  return os;
}

