All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mozilla.javascript.ConsString Maven / Gradle / Ivy

The newest version!
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript;

import java.io.Serializable;

/**
 * 

This class represents a string composed of two components, each of which * may be a java.lang.String or another ConsString.

* *

This string representation is optimized for concatenation using the "+" * operator. Instead of immediately copying both components to a new character * array, ConsString keeps references to the original components and only * converts them to a String if either toString() is called or a certain depth * level is reached.

* *

Note that instances of this class are only immutable if both parts are * immutable, i.e. either Strings or ConsStrings that are ultimately composed * of Strings.

* *

Both the name and the concept are borrowed from V8.

*/ public class ConsString implements CharSequence, Serializable { private static final long serialVersionUID = -8432806714471372570L; private CharSequence s1, s2; private final int length; private int depth; public ConsString(CharSequence str1, CharSequence str2) { s1 = str1; s2 = str2; length = str1.length() + str2.length(); depth = 1; if (str1 instanceof ConsString) { depth += ((ConsString)str1).depth; } if (str2 instanceof ConsString) { depth += ((ConsString)str2).depth; } // Don't let it grow too deep, can cause stack overflows if (depth > 2000) { flatten(); } } // Replace with string representation when serializing private Object writeReplace() { return this.toString(); } @Override public String toString() { return depth == 0 ? (String)s1 : flatten(); } private synchronized String flatten() { if (depth > 0) { StringBuilder b = new StringBuilder(length); appendTo(b); s1 = b.toString(); s2 = ""; depth = 0; } return (String)s1; } private synchronized void appendTo(StringBuilder b) { appendFragment(s1, b); appendFragment(s2, b); } private static void appendFragment(CharSequence s, StringBuilder b) { if (s instanceof ConsString) { ((ConsString)s).appendTo(b); } else { b.append(s); } } public int length() { return length; } public char charAt(int index) { String str = depth == 0 ? (String)s1 : flatten(); return str.charAt(index); } public CharSequence subSequence(int start, int end) { String str = depth == 0 ? (String)s1 : flatten(); return str.substring(start, end); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy