Line data Source code
1 : // Copyright (C) 2009 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.patch; 16 : 17 : import static java.nio.charset.StandardCharsets.ISO_8859_1; 18 : import static java.nio.charset.StandardCharsets.UTF_8; 19 : 20 : import com.google.common.flogger.FluentLogger; 21 : import java.io.IOException; 22 : import java.nio.charset.Charset; 23 : import java.nio.charset.IllegalCharsetNameException; 24 : import java.nio.charset.UnsupportedCharsetException; 25 : import org.eclipse.jgit.diff.RawText; 26 : import org.eclipse.jgit.errors.LargeObjectException; 27 : import org.eclipse.jgit.errors.MissingObjectException; 28 : import org.eclipse.jgit.lib.AnyObjectId; 29 : import org.eclipse.jgit.lib.ObjectLoader; 30 : import org.eclipse.jgit.lib.ObjectReader; 31 : import org.eclipse.jgit.storage.pack.PackConfig; 32 : import org.eclipse.jgit.util.RawParseUtils; 33 : import org.mozilla.universalchardet.UniversalDetector; 34 : 35 : public class Text extends RawText { 36 104 : private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 37 : 38 : private static final int bigFileThreshold = PackConfig.DEFAULT_BIG_FILE_THRESHOLD; 39 : 40 104 : public static final byte[] NO_BYTES = {}; 41 104 : public static final Text EMPTY = new Text(NO_BYTES); 42 : 43 : public static Text forCommit(ObjectReader reader, AnyObjectId commitId) throws IOException { 44 104 : MagicFile commitMessageFile = MagicFile.forCommitMessage(reader, commitId); 45 104 : return new Text(commitMessageFile.getFileContent().getBytes(UTF_8)); 46 : } 47 : 48 : public static Text forMergeList( 49 : ComparisonType comparisonType, ObjectReader reader, AnyObjectId commitId) throws IOException { 50 31 : MagicFile mergeListFile = MagicFile.forMergeList(comparisonType, reader, commitId); 51 31 : return new Text(mergeListFile.getFileContent().getBytes(UTF_8)); 52 : } 53 : 54 : public static byte[] asByteArray(ObjectLoader ldr) 55 : throws MissingObjectException, LargeObjectException, IOException { 56 26 : return ldr.getCachedBytes(bigFileThreshold); 57 : } 58 : 59 : private static Charset charset(byte[] content, String encoding) { 60 35 : if (encoding == null) { 61 35 : UniversalDetector d = new UniversalDetector(null); 62 35 : d.handleData(content, 0, content.length); 63 35 : d.dataEnd(); 64 35 : encoding = d.getDetectedCharset(); 65 : } 66 35 : if (encoding == null) { 67 35 : return ISO_8859_1; 68 : } 69 : try { 70 0 : return Charset.forName(encoding); 71 : 72 0 : } catch (IllegalCharsetNameException err) { 73 0 : logger.atSevere().log("Invalid detected charset name '%s': %s", encoding, err.getMessage()); 74 0 : return ISO_8859_1; 75 : 76 0 : } catch (UnsupportedCharsetException err) { 77 0 : logger.atSevere().log("Detected charset '%s' not supported: %s", encoding, err.getMessage()); 78 0 : return ISO_8859_1; 79 : } 80 : } 81 : 82 : private Charset charset; 83 : 84 : public Text(byte[] r) { 85 104 : super(r); 86 104 : } 87 : 88 : public Text(ObjectLoader ldr) throws MissingObjectException, LargeObjectException, IOException { 89 16 : this(asByteArray(ldr)); 90 16 : } 91 : 92 : public byte[] getContent() { 93 104 : return content; 94 : } 95 : 96 : @Override 97 : protected String decode(int s, int e) { 98 35 : if (charset == null) { 99 35 : charset = charset(content, null); 100 : } 101 35 : return RawParseUtils.decode(charset, content, s, e); 102 : } 103 : }