Beispiel #1
0
Path IniFile::GetPath( const TCHAR* key, const Path& defval ) const
{
#ifdef _UNICODE
	String s = GetStr( key, defval );
	if( s.len()==0 || s[0]!='#' )
		return s;

	// UTF-decoder
	String buf;
	for(uint i=0; 4*i+4<s.len(); ++i)
	{
		unsigned short v = 0;
		for(int j=1; j<=4; ++j)
		{
			int ch = s[4*i+j];
			if( '0'<=ch && ch<='9' ) v = 16*v + ch-'0';
			if( 'a'<=ch && ch<='z' ) v = 16*v + ch-'a'+10;
			if( 'A'<=ch && ch<='Z' ) v = 16*v + ch-'A'+10;
		}
		buf += (wchar_t) v;
	}
	return buf;
#else
	return GetStr( key, defval );
#endif
}
Beispiel #2
0
// default argument n == -1 (replace all)
String String::replace(const String& sub, const String& repl, int n) const {
	if (!n) {
		return *this;
	}

	std::string s = s_data;

	size_t pos = 0;

	while(true) {
		pos = s.find(sub.s_data, pos);
		if (pos == std::string::npos) {
			break;
		}
		s.replace(pos, sub.len(), repl.s_data);
		pos += repl.len();

		if (n > 0) {
			n--;
			if (!n) {
				break;
			}
		}
	}
	return String(s);
}
Beispiel #3
0
String String::lstrip(const String& charset) const {
	if (!s_len) {
		return *this;
	}

	rune tmp[s_len + 1];
	utf8_decode(s_data, tmp, s_len + 1);

	rune tmp_charset[charset.len() + 1];
	utf8_decode(charset.s_data, tmp_charset, charset.len() + 1);

	bool found;

	size_t l = s_len;
	while(l > 0) {
		found = false;
		for(size_t n = 0; n < charset.len(); n++) {
			if (tmp_charset[n] == tmp[0]) {
				found = true;
				break;
			}
		}
		if (!found) {
			break;
		}
		std::memmove(tmp, &tmp[1], l * sizeof(rune));
		l--;
	}
	return String(tmp);
}
Beispiel #4
0
String String::rstrip(const String& charset) const {
	if (!s_len) {
		return *this;
	}

	rune tmp[s_len + 1];
	utf8_decode(s_data, tmp, s_len + 1);

	rune tmp_charset[charset.len() + 1];
	utf8_decode(charset.s_data, tmp_charset, charset.len() + 1);

	bool found;

	int l = s_len - 1;

	while(l >= 0) {
		found = false;
		for(size_t n = 0; n < charset.len(); n++) {
			if (tmp_charset[n] == tmp[l]) {
				found = true;
				break;
			}
		}
		if (!found) {
			break;
		}
		tmp[l--] = 0;
	}
	return String(tmp);
}
Beispiel #5
0
/**
 * Check if the string starts with the given prefix.
 * @param   prefix   Starting string to check for
 * @param   sensy    Case sensitivity
 * @return  True if the string starts with the prefix, false otherwise
 */
bool String::startsWith(const String& prefix, eCaseSensitivity sensy) const
{
   if (!prefix.c_str() || (prefix.len() == 0) || (prefix.len() > length_))
      return false;

   if (sensy == Case)
      return (dStrncmp(prefix.c_str(), pString_, prefix.len()) == 0);
   else
      return (dStrnicmp(prefix.c_str(), pString_, prefix.len()) == 0);
}
Beispiel #6
0
/**
 * Check if the string ends with the given suffix.
 * @param   suffix   Ending string to check for
 * @param   sensy    Case sensitivity
 * @return  True if the string ends with the suffix, false otherwise
 */
bool String::endsWith(const String& suffix, eCaseSensitivity sensy) const
{
   if ((suffix.len() == 0) || (suffix.len() > length_))
      return false;

   const TCHAR* base = pString_ + length_ - suffix.len();

   if (sensy == Case)
      return (dStrncmp(suffix.c_str(), base, suffix.len()) == 0);
   else
      return (dStrnicmp(suffix.c_str(), base, suffix.len()) == 0);
}
Beispiel #7
0
/**
 * Insert a string.
 * @param   s        String to insert
 * @param   index    Position at which to insert the string (-ve values index from the end of the string)
 */
String& String::insert(const String& s, int index)
{
   if (s.len() && _fixIndexAllowEnd(index))
   {
      ASSERT_HALTF((index >= 0) && (index <= length_), "Invalid insertion index (%d)", index);
      ASSERT_HALTF(s.len() > 0, "Invalid insertion string length (%d)", s.len());

      int newLength = length_ + s.len();

      String src;
      src.pString_ = s.pString_;
      src.length_ = s.length_;

      // Check for aliasing (inserting string into itself)
      if ((unsigned int)(src.c_str() - pString_) < (unsigned int)length_)
         src._resize(src.len(), src.len());     // makes a copy of the input string

      // Check if we have space at the start of the buffer to insert the string
      // without resizing
      if (pBuffer_ && (_preLen() >= src.len()))
      {
         pString_ -= src.len();
         dMemmove(pString_, pString_ + src.len(), index);
         dMemcpy(pString_ + index, src.c_str(), src.len());
         length_ = newLength;
      }
      else if (_resize(newLength, length_))
      {
         dMemmove(pString_ + index + src.len(), pString_ + index, length_ - index);
         dMemcpy(pString_ + index, src.c_str(), src.len());
         length_ = newLength;
      }
   }
   return *this;
}
Beispiel #8
0
//-------- Begin of static function disp_version --------//
//
void Game::disp_version()
{
	//----------- display version string --------//

	String str;

	// ####### begin Gilbert 5/6 ########//
//	str  = "Version ";
//	str += GAME_VERSION_STR;
//	#ifdef DEMO
//		str = "Demo Version";
//	#endif
//	#ifdef BETA
//		str = "This is a Beta version. Unauthorized distribution of this Beta is strictly prohibited.";
//	#endif

#if(defined(BETA))
//	str = "This is a Beta version. Unauthorized distribution of this Beta is strictly prohibited.";
	str = text_game_menu.str_beta_version();
#elif(defined(DEMO))
//	str = "Demo Version";
//	str = text_game_menu.str_demo_version();
	str = "";
#else
//	str  = "Version ";
//	str += GAME_VERSION_STR;
	str = text_game_menu.str_version( GAME_VERSION_STR );
#endif
	// ####### end Gilbert 5/6 ########//

	if( str.len() > 40 )
		font_san.center_put( 0, VGA_HEIGHT-20, VGA_WIDTH-1, VGA_HEIGHT-1, str );
	else
		font_zoom.put( VGA_WIDTH-100, 73, str );
}
Beispiel #9
0
/**
 * Combine two strings to form a new string.
 * @param   s1    First string to combine
 * @param   s2    Second string to combine
 * @return  A new string created by appending s2 to the end of s1
 */
String Flib::operator+(const TCHAR* s1, const String& s2)
{
   String cs(s1);
   String s(cs.len() + s2.len());
   s = cs;
   return (s += s2);
}
Beispiel #10
0
void PFPFile::deleteChunk(const String &chunkname)
/*!\brief Chunk nach Namen löschen
 *
 * Mit dieser Funktion werden alle Chunks gelöscht, die den angegebenen Namen haben
 *
 * \param chunkname Pointer auf den Namen des Chunks
 * \returns Die Funktion liefert true (1) zurück, wenn mindestens 1 Chunk gelöscht
 * wurde, sonst false (0).
 * \remarks
 *
 * \see PFPFile::DeleteChunk(PFPChunk *chunk)
 *
 * \since Version 6.1.0
 */
{
	if (chunkname.len()!=4) throw IllegalArgumentException();
	String s=chunkname;
	s.upperCase();
	for (size_t i=0;i<4;i++) {
		wchar_t c=s[i];
		if (c<32 || c>127) throw IllegalArgumentException();
	}
	Iterator it;
	PFPChunk *chunk;
	while ((chunk=findFirstChunk(it,s))) {
		Chunks.erase(chunk);
		delete chunk;
	}
}
Beispiel #11
0
//-------- Begin of static function disp_version --------//
//
void Game::disp_version()
{
	//----------- display version string --------//

	String str;

	str  = _("Version");
	str += " ";
	str += GAME_VERSION_STR;

	#ifdef DEV_VERSION
		str += "-dev";
	#endif

	#ifdef DEBUG
		str += " (DEBUG)";
	#endif

	#ifdef DEMO
		str = "Demo Version";
	#endif

	#ifdef BETA
		str = "This is a Beta version. Unauthorized distribution of this Beta is illegal.";
	#endif

	if( str.len() > 40 )
		font_news.center_put( 0, VGA_HEIGHT-20, VGA_WIDTH-1, VGA_HEIGHT-1, str );
	else
		font_news.right_put( VGA_WIDTH-10, VGA_HEIGHT-20, str );
}
Beispiel #12
0
void FarMenu::SetItemText(FarMenuItem* item, const String& text)
{
	size_t len = text.len() + 1;
	wchar_t* t = new wchar_t[len];
	text.copyTo(t, len);
	item->Text = t;
}
Beispiel #13
0
String::String (const String& s) 
{
    length = s.len();
    data   = new char[length];
    for (unsigned j=0; j < length; j++)
        data[j] = s[j];
}
Beispiel #14
0
	int AsmBuf::getParmList(String *plist[])
	{
		String *id;
		int Depth = 0, c, count;

		for (count = 0; count < MAX_MACRO_PARMS; count++) {
			if (plist[count])
				delete plist[count];
			plist[count] = NULL;
		}
		count = 0;
		while(1)
		{
			id = getArg();
			//printf("arg:%s|\r\n", id->buf());
			if (id)
			{
				if (id->len())
				{
					if (count >= MAX_MACRO_PARMS)
					{
						Err(E_MACROPARM);
						delete id;
						goto errxit;
					}
					plist[count] = id;
					count++;
				}
				else
					delete id;
			}
			c = nextNonSpaceLF();

			// Comment ?
			if (c == ';') {
				unNextCh();
				break;
			}
			// Look and see if we got the last parameter
			if (c < 1 || c == '\n')
			{
				unNextCh();
				break;
			}
			if (c != ',')
			{
				Err(E_MACROCOMMA); // expecting ',' separator
				goto errxit;
			}
		}
		//   if (count < 1)
		//      err(17);
		if (count < MAX_MACRO_PARMS)
			plist[count] = NULL;
		errxit:;
		return (count);
	}
Beispiel #15
0
void GreenPadWnd::on_datetime()
{
	String g = cfg_.dateFormat();
	TCHAR buf[255], tmp[255];
	::GetTimeFormat
		( LOCALE_USER_DEFAULT, 0, NULL, g.len()?const_cast<TCHAR*>(g.c_str()):TEXT("HH:mm yyyy/MM/dd"), buf, countof(buf));
	::GetDateFormat
		( LOCALE_USER_DEFAULT, 0, NULL, buf, tmp,countof(tmp));
	edit_.getCursor().Input( tmp, ::lstrlen(tmp) );
}
Beispiel #16
0
extern "C" int main()
{
    char buff[33];
    char *tokens = NULL;
    unsigned count = 0;
    const char *tp;
    const char *array[5];

    assert(max(3, 2) == 3);

    String::fill(buff, 32, ' ');
    stringbuf<128> mystr;
    mystr = (string_t)"hello" + (string_t)" this is a test";
    assert(eq_case("hello this is a test", *mystr));
    assert(eq_case("second test", *testing));
    assert(eq_case(" Is a test", mystr(-10)));
    mystr = "  abc 123 \n  ";
    assert(eq_case("abc 123", String::strip(mystr.c_mem(), " \n")));
    String::set(buff, sizeof(buff), "this is \"a test\"");
    while(NULL != (tp = String::token(buff, &tokens, " ", "\"\"")) && count < 4)
        array[count++] = tp;
    assert(count == 3);
    assert(eq_case(array[1], "is"));
    assert(eq_case(array[2], "a test"));

    unsigned char core[4] = {0x01, 0x10, 0x2f, 0x45};
    char hexbuf[12];

    assert(String::hexdump(core, hexbuf, "3-1") == 9);
    assert(eq(hexbuf, "01102f-45"));

    unsigned char hcore[4];

    String::hexpack(hcore, hexbuf, "3-1");
    assert(String::hexdump(hcore, hexbuf, "3-1") == 9);
    assert(eq(hexbuf, "01102f-45"));

    String numstr = "-33.5,25";
    Real num1;
    Unsigned num2;

    numstr % num1 % "," % num2;
    assert(num1 == -33.5);
    assert(num2 == 25);
    assert(numstr.len() == 0);

    char *test = strdup(str("hello") + " test" + str((short)13));
    assert(eq(test, "hello test13"));

    char *cdup = dup<char>(test[6]);
    assert(eq(cdup, "test13"));

    return 0;
}
Beispiel #17
0
/**
 * Internal helper function for string concatenation operations.
 * @param   s     String to append
 */
void String::_append(const String& s)
{
   ASSERT_HALTF(s.len() >= 0, "Invalid length (%d). Must be >= 0");
   int newLength = length_ + s.len();

   // Always resize (just in case we have no memory allocated yet)
   if (_resize(newLength, length_))
   {
      /* Check for aliasing (appending string to itself) */
      if ((unsigned int)(s.c_str() - pString_) < (unsigned int)length_)
      {
         int offset = (int)(s.c_str() - pString_);
         dMemcpy(pString_ + length_, pString_ + offset, s.len());
      }
      else
      {
         dMemcpy(pString_ + length_, s.c_str(), s.len());
      }
      length_ = newLength;
   }
}
Beispiel #18
0
bool FileMgr::exists(String str)
{
   // folders - they can't have a trailing slash
   if (str.endsWith("/"))
   {
      str = str.substr(0, str.len() - 1);
   }

   struct stat foo;
   int ret = stat(str.cStr(), &foo);
   return ret == 0 ? true : false;
}
Beispiel #19
0
//-------- Begin of static function disp_version --------//
//
void Game::disp_version()
{
	//----------- display version string --------//

	String str;

	str = text_game_menu.str_version( GAME_VERSION_STR );

	if( str.len() > 40 )
		font_san.center_put( 0, VGA_HEIGHT-20, VGA_WIDTH-1, VGA_HEIGHT-1, str );
	else
		font_zoom.put( VGA_WIDTH-100, 73, str );
}
Beispiel #20
0
double SToD(const String & s)    // String to double
{
    double res = 0;
    int indexpoint = -1;
    int i, j, k;
    int sign = 1;
    char num[numsize];
    char front = '\0';
    for (i = 0, j = 0; i < s.len(); i++)
    {
        if (isdigit(s[i]))    // deal with number
            num[j++] = s[i];
        else if (s[i] == '.' && indexpoint == -1 && isdigit(front))    // deal with point
        {
            num[j++] = s[i];
            indexpoint = j - 1;    // one double number can only have one point
        }
        else if (isdigit(front) || front == '.')    // deal with others and end reading
            break;
        if (s[i] == '-')    // deal with the minus
            sign *= -1;
        front = s[i];
    }
    num[j] = '\0';
    if (indexpoint == -1)
    {
        k = j - 1;
        for (i = k; i >= 0; i--)    // only integer part
        {
            res += pow(10, k - i) * ChToI(num[i]);
        }
    }
    else
    {
        k = indexpoint - 1;
        for (i = k; i >= 0; i--)    // integer part
        {
            res += pow(10, k - i) * ChToI(num[i]);
        }
        k = indexpoint + 1;
        for (i = k; i < j; i++)    // decimal part
        {
            res += pow(0.1, i + 1 - k) * ChToI(num[i]);
        }
    }
    res *= sign;
    return res;
}
Beispiel #21
0
String String::replace(const String & what, const String & with) const
{
  if (what.empty())
  {
    return *this;
  }
  String res;
  intptr_t start = 0;
  intptr_t p;
  while ((p = find(what, start)) != -1)
  {
    res += substr(start, p - start);
    res += with;
    start = p + what.len();
  }
  res += substr(start);
  return res;
}
Beispiel #22
0
// default arguments start=0, end=0
int String::rfind(const String& s, int start, int end) const {
	if (start < 0) {
		start += s_len;

		if (start < 0) {
			return -1;
		}
	}

	// end must be at least at 'distance' of length of search string
	end -= s.len();

	if (end <= 0) {
		end += s_len;

		if (end <= 0) {
			return -1;
		}
	}
	if ((size_t)end > s_len) {
		end = len();
	}
	if ((size_t)start >= s_len || start > end) {
		return -1;
	}

	rune tmp[s_len + 1];
	utf8_decode(s_data, tmp, s_len + 1);

	rune tmp2[s.s_len + 1];
	utf8_decode(s.s_data, tmp2, s.s_len + 1);

	int pos;
	for(pos = end; pos >= start; pos--) {
		if (!std::memcmp(&tmp[pos], tmp2, sizeof(rune) * s.s_len)) {
			break;
		}
	}
	if (pos < start) {
		pos = -1;
	}
	return pos;
}
Beispiel #23
0
void PFPFile::setId(const String &id)
/*!\brief ID des PFP-Files setzen
 *
 * Mit dieser Version wird die ID des PFP-Files festgelegt. Eine ID muss zwingend 4 Byte lang
 * sein und darf nur US-ASCII-Zeichen enthalten.
 *
 * \param id Pointer auf einen 4-Byte langen String, der mit 0 terminiert ist.
 * \exception IllegalArgumentException Wird geworfen, wenn die \p id einen ungültigen Wert enthält
 *
 * \since Version 6.1.0
 */
{
	if (id.len()!=4) throw IllegalArgumentException();
	for (size_t i=0;i<4;i++) {
		wchar_t c=id[i];
		if (c<32 || c>127) throw IllegalArgumentException();
	}
	this->id=id;
}
Beispiel #24
0
int main() {
    TextFile file;
    String s;
    if (file.open("birthday.in")) {
        while (true) {
            String f = file.read_line();
            if (f.is_empty()) {
                break;
            }
            s += f;
        }
    }
    
    for (int i = 0; i < s.len(); i += 1) {
        
    }
    

    return 0;
}
Beispiel #25
0
void TimeFmt::printCustom(int sec, const char *buf, int bufsize, const char *str_sep, const char *str_seconds, const char *str_minutes, const char *str_hours, const char *str_days) {
  if (buf == NULL || bufsize == 0) return;
  char *p = (char *)buf;
  *p = 0;
  int days, hours, minutes;
  String s;

  if (str_days) {
    days = sec / (3600*24);
    sec -= days * (3600*24);
    if (days != 0) {
      s += StringPrintf("%d%s", days, str_days);
    }
  }
  if (str_hours) {
    hours = sec / 3600;
    sec -= hours * 3600;
    if (hours != 0) {
      if (!s.isempty()) s += str_sep;
      s += StringPrintf("%d%s", hours, str_hours);
    }
  }
  if (str_minutes) {
    minutes = sec / 60;
    sec -= minutes * 60;
    if (minutes != 0) {
      if (!s.isempty()) s += str_sep;
      s += StringPrintf("%d%s", minutes, str_minutes);
    }
  }
  if (str_seconds) {
    if (sec != 0) {
      if (!s.isempty()) s += str_sep;
      s += StringPrintf("%d%s", sec, str_seconds);
    }
  }
  STRNCPY(p, s.getValue(), bufsize);
  int l = s.len();
  if (l < bufsize) p[l] = 0;
}
Beispiel #26
0
void PFPChunk::setName(const String &chunkname)
/*!\brief Name des Chunks setzen
 *
 * \desc
 * Mit dieser Funktion wird der Name eines Chunks definiert. Der Name muss
 * exakt 4 Byte lang sein und darf nur Großbuchstaben enthalten (es wird
 * eine automatische Konvertierung durchgeführt). Ausserdem sind nur Zeichen
 * aus dem Zeichensatz US-ASCII erlaubt.
 *
 * \param chunkname String mit dem Namen des Strings
 * \exception IllegalArgumentException Wird geworfen, wenn der Name des Chunks ungültig ist
 *
 */
{
	if (chunkname.len()!=4) throw IllegalArgumentException();
	String s=chunkname;
	s.upperCase();
	for (size_t i=0;i<4;i++) {
		wchar_t c=s[i];
		if (c<32 || c>127) throw IllegalArgumentException();
	}
	this->chunkname=s;
}
Beispiel #27
0
String operator + (char const * a, String const & b) {
  char temp [strlen (a) + b.len () + 1];
  strcpy (temp, a);
  strcpy (temp+strlen(a), b.data);
  return temp;
}
Beispiel #28
0
//-------- Begin of static function put_spy_rec --------//
//
static void put_spy_rec(int recNo, int x, int y, int refreshFlag)
{
	int  spyRecno = spy_filter(recNo);
	Spy* spyPtr   = spy_array[spyRecno];

	x+=3;
	y+=5;

	//------ display rank/skill icon -------//

	int 	 cloakedRankId  = spyPtr->cloaked_rank_id();
	int 	 cloakedSkillId = spyPtr->cloaked_skill_id();
	String str;

	switch( cloakedRankId )
	{
		case RANK_KING:
			str = "U_KING";
			break;

		case RANK_GENERAL:
			str = "U_GENE";
			break;

		case RANK_SOLDIER:
			if( cloakedSkillId )
			{
				str  = "U_";
				str += Skill::skill_code_array[cloakedSkillId-1];
			}
			else
			{
				str = "";
			}
			break;
	}

	if( str.len() > 0 )
		image_icon.put_back(x, y+1, str);

	//------ display race icon -------------//

	vga_back.put_bitmap( x+13, y-4, race_res[spyPtr->race_id]->icon_bitmap_ptr );

	//----------- display name -----------//

	font_san.put( x+39, y, race_res[spyPtr->race_id]->get_name(spyPtr->name_id), 0, 185 );

	//------- display cloaked nation color ------//

	int tx = x+170;

	if( spyPtr->cloaked_nation_recno==0 )		// independent nation
	{
		vga_back.bar( tx, y, tx+12, y+12, V_WHITE );
		vga_back.rect( tx, y, tx+12, y+12, 1, VGA_GRAY+8 );
	}
	else
	{
		nation_array[spyPtr->cloaked_nation_recno]->disp_nation_color(tx, y+2);
	}

	//---------- display other info ----------//

	switch( spyPtr->spy_place )
	{
		case SPY_FIRM:
			str = firm_res[firm_array[spyPtr->spy_place_para]->firm_id]->name;
			break;

		case SPY_TOWN:
			str = town_array[spyPtr->spy_place_para]->town_name();
			break;

		case SPY_MOBILE:
		{
			Unit* unitPtr = unit_array[spyPtr->spy_place_para];

			switch( unitPtr->unit_mode )
			{
				case UNIT_MODE_CONSTRUCT:
					str = firm_res[firm_array[unitPtr->unit_mode_para]->firm_id]->name;
					break;

				case UNIT_MODE_ON_SHIP:
					str = "On Ship";
					break;

				default:
					str = "Mobile";
			}
			break;
		}

		default:
			str = "";
	}

	font_san.put( x+205, y, str );

	font_san.put( x+335, y, spyPtr->spy_skill );
	font_san.put( x+385, y, spyPtr->spy_loyalty );
	font_san.put( x+435, y, spyPtr->action_str() );
}
Beispiel #29
0
/**
 * Combine two strings to form a new string.
 * @param   s2    String to append
 * @return  A new string created by appending s2 to the end of this string
 */
String String::operator+(const String& s2) const
{
   String s1(len() + s2.len());
   s1 = *this;
   return (s1 += s2);
}
Beispiel #30
0
//------------------------------------------------------------------------------
// setString() --
//------------------------------------------------------------------------------
void String::setString(const String& origStr, const size_t w, const Justify j)
{
   char sbuf[MAX_STRING_LENGTH+1];  // Source buffer
   char dbuf[MAX_STRING_LENGTH+1];  // Destination buffer
   const char* ss = sbuf;           // Pointer to source buffer


   // ---
   // when w is zero or origStr is empty
   // ---

   if (w == 0 || origStr.len() == 0) {
      dbuf[0] = '\0';
      *this = dbuf;
      return;
   }

   // ---
   // When justified (left, right, center), make the copy without leading
   // or trailing spaces.
   // ---

   if (j != NONE) {
      // Justified:  copy without leading or trailing spaces
      const char* p = origStr;
      char* q = sbuf;
      while (*p != '\0' && *p == ' ') { p++; }
      while (*p != '\0' && q <= &sbuf[MAX_STRING_LENGTH-1]) { *q++ = *p++; }
      *q-- = '\0';
      while (*q == ' ' && q >= sbuf) { *q-- = ' '; }
   }
   else {
      // Not justified:  change our source buffer pointer to the orig string
      ss = origStr;
   }


   // ---
   // Set this to the new string justified
   // ---

   int i1 = 0;                  // Source index
   int i2 = 0;                  // Destination index
   int l1 = int(strlen(ss));    // Source string length
   if (l1 > MAX_STRING_LENGTH) l1 = MAX_STRING_LENGTH;
   int l2 = int(w);             // Destination string length
   if (l2 > MAX_STRING_LENGTH) l2 = MAX_STRING_LENGTH;
   int d = l2 - l1;             // Difference in lengths

   switch (j) {

      // NONE or LEFT justified
      case NONE :
      case LEFT :
      {
         if (d < 0) l1 += d;
         while (i1 < l1) { dbuf[i2++] = ss[i1++]; }
         while (i2 < l2) { dbuf[i2++] = ' '; }
      }
      break;

      // RIGHT justified
      case RIGHT : {
         if (d < 0) i1 = -d;
         while (i2 < d)  { dbuf[i2++] = ' '; }
         while (i1 < l1) { dbuf[i2++] = ss[i1++]; }
      }
      break;

      // CENTER justified
      case CENTER : {
         int n1 = d/2;
         if (d < 0) { i1 = -n1; l1 += (d-n1); }
         while (i2 < n1) { dbuf[i2++] = ' '; }
         while (i1 < l1) { dbuf[i2++] = ss[i1++]; }
         while (i2 < l2) { dbuf[i2++] = ' '; }
      }
      break;
   }

   dbuf[i2] = '\0';
   *this = dbuf;
}