/** * Copyright 2010 Google Inc. * * Licensed 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. * */ package org.waveprotocol.wave.client.common.util; import com.google.gwt.core.client.GWT; /** * Provides cross-platform encoding and decoding of arbitrary strings. * */ public interface StringCodec { /** * A basic codec that moves the string to an alphabet that does not include * commas. Decoding restores the original string. This allows commas to be * used to mark structure (like Godel numbering). */ public StringCodec INSTANCE = GWT.isScript() ? new JsCodec() : new JavaCodec(); /** * Encodes a string. This method provides the contract that, for any input * string: * <ul> * <li>decode(encode(s)) == s; and</li> * <li>encode(s) contains no characters from the set free()</li> * </ul> * * @param s string to encode * @return encoding of {@code s} */ String encode(String s); /** * Decodes a string encoded by {@link #encode(String)}. * * @param s string to decode * @return decoding of {@code s} */ String decode(String s); /** The characters that are removed from the alphabet encoded strings. */ String free(); // // Default implementations below. // // Simple quotation logic: // 1. & --> && (promotes & as the quote char) // 2. , --> &c (removes commas from alphabet) // // Unquotation is the inverse: // 1. &c --> , (reinserts commas into alphabet) // 2. && --> & (demotes & from being the quote char) // // final class JsCodec implements StringCodec { @Override public String free() { return ","; } @Override public native String encode(String s) /*-{ return s.replace(/&/g, "&&").replace(/,/g, "&c"); }-*/; @Override public native String decode(String s) /*-{ return s.replace(/&c/g, ",").replace(/&&/g, "&"); }-*/; } final class JavaCodec implements StringCodec { @Override public String free() { return ","; } @Override public String encode(String s) { return s.replace("&", "&&").replace(",", "&c"); } @Override public String decode(String s) { return s.replace("&c", ",").replace("&&", "&"); } } }