That fuck shit the fascists are using
at master 174 lines 5.2 kB view raw
1package org.tm.archive.profiles; 2 3import android.os.Parcel; 4import android.os.Parcelable; 5 6import androidx.annotation.NonNull; 7import androidx.annotation.Nullable; 8import androidx.annotation.VisibleForTesting; 9 10import com.annimon.stream.Stream; 11 12import org.signal.core.util.StringUtil; 13import org.tm.archive.util.cjkv.CJKVUtil; 14import org.whispersystems.signalservice.api.crypto.ProfileCipher; 15 16import java.util.Objects; 17 18public final class ProfileName implements Parcelable { 19 20 public static final ProfileName EMPTY = new ProfileName("", ""); 21 public static final int MAX_PART_LENGTH = (ProfileCipher.MAX_POSSIBLE_NAME_LENGTH - 1) / 2; 22 23 private final String givenName; 24 private final String familyName; 25 private final String joinedName; 26 27 private ProfileName(@Nullable String givenName, @Nullable String familyName) { 28 this.givenName = givenName == null ? "" : givenName; 29 this.familyName = familyName == null ? "" : familyName; 30 this.joinedName = getJoinedName(this.givenName, this.familyName); 31 } 32 33 private ProfileName(Parcel in) { 34 this(in.readString(), in.readString()); 35 } 36 37 public @NonNull String getGivenName() { 38 return givenName; 39 } 40 41 public @NonNull String getFamilyName() { 42 return familyName; 43 } 44 45 @VisibleForTesting 46 boolean isProfileNameCJKV() { 47 return isCJKV(givenName, familyName); 48 } 49 50 public boolean isEmpty() { 51 return joinedName.isEmpty(); 52 } 53 54 public boolean isGivenNameEmpty() { 55 return givenName.isEmpty(); 56 } 57 58 public @NonNull String serialize() { 59 if (isGivenNameEmpty()) { 60 return ""; 61 } else if (familyName.isEmpty()) { 62 return givenName; 63 } else { 64 return String.format("%s\0%s", givenName, familyName); 65 } 66 } 67 68 @Override 69 public @NonNull String toString() { 70 return joinedName; 71 } 72 73 /** 74 * Deserializes a profile name, trims if exceeds the limits. 75 */ 76 public static @NonNull ProfileName fromSerialized(@Nullable String profileName) { 77 if (profileName == null || profileName.isEmpty()) { 78 return EMPTY; 79 } 80 81 String[] parts = profileName.split("\0"); 82 83 if (parts.length == 0) { 84 return EMPTY; 85 } else if (parts.length == 1) { 86 return fromParts(parts[0], ""); 87 } else { 88 return fromParts(parts[0], parts[1]); 89 } 90 } 91 92 /** 93 * Creates a profile name that only contains a given name. 94 */ 95 public static @NonNull ProfileName asGiven(@Nullable String givenName) { 96 return fromParts(givenName, null); 97 } 98 99 /** 100 * Creates a profile name, trimming chars until it fits the limits. 101 */ 102 public static @NonNull ProfileName fromParts(@Nullable String givenName, @Nullable String familyName) { 103 givenName = givenName == null ? "" : givenName; 104 familyName = familyName == null ? "" : familyName; 105 106 givenName = StringUtil.trimToFit(givenName.trim(), ProfileName.MAX_PART_LENGTH); 107 familyName = StringUtil.trimToFit(familyName.trim(), ProfileName.MAX_PART_LENGTH); 108 109 if (givenName.isEmpty() && familyName.isEmpty()) { 110 return EMPTY; 111 } 112 113 return new ProfileName(givenName, familyName); 114 } 115 116 private static @NonNull String getJoinedName(@NonNull String givenName, @NonNull String familyName) { 117 if (givenName.isEmpty() && familyName.isEmpty()) return ""; 118 else if (givenName.isEmpty()) return familyName; 119 else if (familyName.isEmpty()) return givenName; 120 else if (isCJKV(givenName, familyName)) return String.format("%s %s", 121 familyName, 122 givenName); 123 else return String.format("%s %s", 124 givenName, 125 familyName); 126 } 127 128 private static boolean isCJKV(@NonNull String givenName, @NonNull String familyName) { 129 if (givenName.isEmpty() && familyName.isEmpty()) { 130 return false; 131 } else { 132 return Stream.of(givenName, familyName) 133 .filterNot(String::isEmpty) 134 .reduce(true, (a, s) -> a && CJKVUtil.isCJKV(s)); 135 } 136 } 137 138 @Override 139 public int describeContents() { 140 return 0; 141 } 142 143 @Override 144 public void writeToParcel(Parcel dest, int flags) { 145 dest.writeString(givenName); 146 dest.writeString(familyName); 147 } 148 149 @Override 150 public boolean equals(Object o) { 151 if (this == o) return true; 152 if (o == null || getClass() != o.getClass()) return false; 153 ProfileName that = (ProfileName) o; 154 return Objects.equals(givenName, that.givenName) && 155 Objects.equals(familyName, that.familyName); 156 } 157 158 @Override 159 public int hashCode() { 160 return Objects.hash(givenName, familyName); 161 } 162 163 public static final Creator<ProfileName> CREATOR = new Creator<ProfileName>() { 164 @Override 165 public ProfileName createFromParcel(Parcel in) { 166 return new ProfileName(in); 167 } 168 169 @Override 170 public ProfileName[] newArray(int size) { 171 return new ProfileName[size]; 172 } 173 }; 174}