001package squidpony.store.json; 002 003import com.badlogic.gdx.files.FileHandle; 004import com.badlogic.gdx.utils.Json; 005import com.badlogic.gdx.utils.JsonWriter; 006import com.badlogic.gdx.utils.SerializationException; 007import squidpony.LZSPlus; 008 009import java.io.InputStream; 010import java.io.Reader; 011import java.io.Writer; 012 013/** 014 * A variant of {@link JsonConverter} (and an extension of libGDX's {@link Json} class) that 015 * compresses its JSON output and reads compressed input. Due to limits on the String compression library this uses 016 * (namely, it only compresses Strings, so input must be able to be interpreted as a String), this only allows String 017 * and FileHandle input formats, and throws exceptions if you try to deserialize a char array, InputStream, or Reader 018 * with fromJson() . Otherwise, it acts like JsonConverter, so the same docs apply: 019 * <br> 020 * Augmented version of LibGDX's Json class that knows how to handle various data types common in SquidLib. 021 * This includes OrderedMap, which notably allows non-String keys (LibGDX's default Map serializer requires keys to be 022 * Strings), but does not currently allow the IHasher to be set (which only should affect OrderedMaps with array keys). 023 * It also makes significantly shorter serialized output for 2D char arrays, GreasedRegion and FakeLanguageGen objects, 024 * and various collections (IntDoubleOrderedMap, IntVLA, Arrangement, K2, and K2V1 at least). 025 * Created by Tommy Ettinger on 1/9/2017. 026 */ 027public class JsonCompressor extends Json { 028 public JsonCompressor() { 029 super(); 030 JsonConverter.initialize(this); 031 } 032 033 public JsonCompressor(JsonWriter.OutputType outputType) { 034 super(outputType); 035 JsonConverter.initialize(this); 036 } 037 038 /** 039 * @param object The object to serialize 040 * @param knownType May be null if the type is unknown. 041 * @param elementType May be null if the type is unknown. 042 */ 043 @Override 044 public String toJson(Object object, Class knownType, Class elementType) { 045 return LZSPlus.compress(super.toJson(object, knownType, elementType)); 046 } 047 048 /** 049 * @param object The object to serialize 050 * @param knownType May be null if the type is unknown. 051 * @param elementType May be null if the type is unknown. 052 * @param file A LibGDX FileHandle that can be written to; overwrites, does not append 053 */ 054 @Override 055 public void toJson (Object object, Class knownType, Class elementType, FileHandle file) { 056 try { 057 file.writeString(this.toJson(object, knownType, elementType), false, "UTF-8"); 058 } catch (Exception ex) { 059 throw new SerializationException("Error writing file: " + file, ex); 060 } 061 } 062 063 /** 064 * Don't use this, please! This method doesn't compress its output. 065 * @param object The object to serialize 066 * @param knownType May be null if the type is unknown. 067 * @param elementType May be null if the type is unknown. 068 * @param writer A Writer that will be the recipient of this class' JSON output 069 */ 070 @Override 071 @Deprecated 072 public void toJson(Object object, Class knownType, Class elementType, Writer writer) { 073 super.toJson(object, knownType, elementType, writer); 074 } 075 076 /** 077 * @param type May be null if the type is unknown. 078 * @param reader 079 * @return May be null. 080 */ 081 @Override 082 public <T> T fromJson(Class<T> type, Reader reader) { 083 throw new UnsupportedOperationException("fromJson() given a char[], Reader or InputStream won't decompress;" + 084 "use the overloads that take a String or FileHandle instead"); 085 } 086 087 /** 088 * @param type May be null if the type is unknown. 089 * @param elementType May be null if the type is unknown. 090 * @param reader 091 * @return May be null. 092 */ 093 @Override 094 public <T> T fromJson(Class<T> type, Class elementType, Reader reader) { 095 throw new UnsupportedOperationException("fromJson() given a char[], Reader or InputStream won't decompress;" + 096 "use the overloads that take a String or FileHandle instead"); 097 } 098 099 /** 100 * @param type May be null if the type is unknown. 101 * @param input 102 * @return May be null. 103 */ 104 @Override 105 public <T> T fromJson(Class<T> type, InputStream input) { 106 throw new UnsupportedOperationException("fromJson() given a char[], Reader or InputStream won't decompress;" + 107 "use the overloads that take a String or FileHandle instead"); 108 } 109 110 /** 111 * @param type May be null if the type is unknown. 112 * @param elementType May be null if the type is unknown. 113 * @param input 114 * @return May be null. 115 */ 116 @Override 117 public <T> T fromJson(Class<T> type, Class elementType, InputStream input) { 118 throw new UnsupportedOperationException("fromJson() given a char[], Reader or InputStream won't decompress;" + 119 "use the overloads that take a String or FileHandle instead"); 120 } 121 122 /** 123 * @param type May be null if the type is unknown. 124 * @param file 125 * @return May be null. 126 */ 127 @Override 128 public <T> T fromJson(Class<T> type, FileHandle file) { 129 return super.fromJson(type, LZSPlus.decompress(file.readString("UTF-8"))); 130 } 131 132 /** 133 * @param type May be null if the type is unknown. 134 * @param elementType May be null if the type is unknown. 135 * @param file 136 * @return May be null. 137 */ 138 @Override 139 public <T> T fromJson(Class<T> type, Class elementType, FileHandle file) { 140 return super.fromJson(type, elementType, LZSPlus.decompress(file.readString("UTF-8"))); 141 } 142 143 /** 144 * @param type May be null if the type is unknown. 145 * @param data 146 * @param offset 147 * @param length 148 * @return May be null. 149 */ 150 @Override 151 public <T> T fromJson(Class<T> type, char[] data, int offset, int length) { 152 throw new UnsupportedOperationException("fromJson() given a char[], Reader or InputStream won't decompress;" + 153 "use the overloads that take a String or FileHandle instead"); 154 } 155 156 /** 157 * @param type May be null if the type is unknown. 158 * @param elementType May be null if the type is unknown. 159 * @param data 160 * @param offset 161 * @param length 162 * @return May be null. 163 */ 164 @Override 165 public <T> T fromJson(Class<T> type, Class elementType, char[] data, int offset, int length) { 166 throw new UnsupportedOperationException("fromJson() given a char[], Reader or InputStream won't decompress;" + 167 "use the overloads that take a String or FileHandle instead"); 168 } 169 170 /** 171 * @param type May be null if the type is unknown. 172 * @param json 173 * @return May be null. 174 */ 175 @Override 176 public <T> T fromJson(Class<T> type, String json) { 177 return super.fromJson(type, LZSPlus.decompress(json)); 178 } 179 180 /** 181 * @param type May be null if the type is unknown. 182 * @param elementType 183 * @param json 184 * @return May be null. 185 */ 186 @Override 187 public <T> T fromJson(Class<T> type, Class elementType, String json) { 188 return super.fromJson(type, elementType, LZSPlus.decompress(json)); 189 } 190}