using new json serialization implementation

This commit is contained in:
Mariotaku Lee 2015-04-23 15:40:11 +08:00
parent 19a91578da
commit 451a4d8df7
13 changed files with 395 additions and 395 deletions

View File

@ -26,7 +26,6 @@ import android.os.Parcelable;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import org.mariotaku.twidere.util.SimpleValueSerializer;
import org.mariotaku.twidere.util.TwitterContentUtils;
import java.util.Comparator;
@ -93,7 +92,7 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
id = getAsLong(values, DirectMessages.MESSAGE_ID, -1);
is_outgoing = getAsBoolean(values, DirectMessages.IS_OUTGOING, false);
account_id = getAsLong(values, DirectMessages.ACCOUNT_ID, -1);
media = SimpleValueSerializer.fromSerializedString(values.getAsString(DirectMessages.MEDIA_LIST), ParcelableMedia.SIMPLE_CREATOR);
media = ParcelableMedia.fromSerializedJson(values.getAsString(DirectMessages.MEDIA_JSON));
}
public ParcelableDirectMessage(final Cursor c, final CursorIndices idx) {
@ -114,7 +113,7 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
: null;
recipient_profile_image_url = idx.recipient_profile_image_url != -1 ? c
.getString(idx.recipient_profile_image_url) : null;
media = SimpleValueSerializer.fromSerializedString(idx.media != -1 ? c.getString(idx.media) : null, ParcelableMedia.SIMPLE_CREATOR);
media = idx.media != -1 ? ParcelableMedia.fromSerializedJson(c.getString(idx.media)) : null;
}
public ParcelableDirectMessage(final DirectMessage message, final long account_id, final boolean is_outgoing) {
@ -247,7 +246,7 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
recipient_screen_name = cursor.getColumnIndex(DirectMessages.RECIPIENT_SCREEN_NAME);
sender_profile_image_url = cursor.getColumnIndex(DirectMessages.SENDER_PROFILE_IMAGE_URL);
recipient_profile_image_url = cursor.getColumnIndex(DirectMessages.RECIPIENT_PROFILE_IMAGE_URL);
media = cursor.getColumnIndex(DirectMessages.MEDIA_LIST);
media = cursor.getColumnIndex(DirectMessages.MEDIA_JSON);
}
}
}

View File

@ -5,18 +5,21 @@ import android.os.Parcelable;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.JsonReader;
import android.util.JsonWriter;
import org.mariotaku.jsonserializer.JSONParcel;
import org.mariotaku.jsonserializer.JSONParcelable;
import org.mariotaku.twidere.model.iface.JsonReadable;
import org.mariotaku.twidere.model.iface.JsonWritable;
import org.mariotaku.twidere.util.JsonSerializationUtils;
import org.mariotaku.twidere.util.MediaPreviewUtils;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.SimpleValueSerializer;
import org.mariotaku.twidere.util.SimpleValueSerializer.Reader;
import org.mariotaku.twidere.util.SimpleValueSerializer.SerializationException;
import org.mariotaku.twidere.util.SimpleValueSerializer.SimpleValueSerializable;
import org.mariotaku.twidere.util.SimpleValueSerializer.Writer;
import org.mariotaku.twidere.util.TwidereArrayUtils;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -34,7 +37,78 @@ import twitter4j.Status;
import twitter4j.URLEntity;
@SuppressWarnings("unused")
public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueSerializable {
public class ParcelableMedia implements Parcelable, JSONParcelable, JsonReadable, JsonWritable {
public static ParcelableMedia[] fromSerializedJson(String string) {
if (TextUtils.isEmpty(string)) return null;
JsonReader reader = new JsonReader(new StringReader(string));
try {
reader.beginArray();
final ParcelableMedia[] media = JsonSerializationUtils.array(reader, ParcelableMedia.class);
reader.endArray();
return media;
} catch (IOException ignore) {
return null;
} finally {
try {
reader.close();
} catch (IOException ignore) {
}
}
}
@Override
public void read(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "media_url": {
media_url = reader.nextString();
break;
}
case "page_url": {
page_url = reader.nextString();
break;
}
case "preview_url": {
preview_url = reader.nextString();
break;
}
case "start": {
start = reader.nextInt();
break;
}
case "end": {
end = reader.nextInt();
break;
}
case "type": {
//noinspection ResourceType
type = reader.nextInt();
break;
}
case "width": {
width = reader.nextInt();
break;
}
case "height": {
height = reader.nextInt();
break;
}
case "video_info": {
reader.beginObject();
video_info = JsonSerializationUtils.object(reader, VideoInfo.class);
reader.endObject();
break;
}
default: {
reader.skipValue();
break;
}
}
}
reader.endObject();
}
@IntDef({TYPE_UNKNOWN, TYPE_IMAGE, TYPE_VIDEO, TYPE_ANIMATED_GIF, TYPE_CARD_ANIMATED_GIF})
public @interface MediaType {
@ -76,17 +150,6 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
}
};
public static final SimpleValueSerializer.Creator<ParcelableMedia> SIMPLE_CREATOR = new SimpleValueSerializer.Creator<ParcelableMedia>() {
@Override
public ParcelableMedia create(final SimpleValueSerializer.Reader reader) throws SerializationException {
return new ParcelableMedia(reader);
}
@Override
public ParcelableMedia[] newArray(final int size) {
return new ParcelableMedia[size];
}
};
@NonNull
public String media_url;
@ -107,6 +170,7 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
}
public ParcelableMedia(final JSONParcel in) {
media_url = in.readString("media_url");
page_url = in.readString("page_url");
@ -188,50 +252,6 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
this.height = 0;
}
public ParcelableMedia(Reader reader) throws SerializationException {
while (reader.hasKeyValue()) {
switch (reader.nextKey()) {
case "media_url": {
media_url = reader.nextString();
break;
}
case "page_url": {
page_url = reader.nextString();
break;
}
case "preview_url": {
preview_url = reader.nextString();
break;
}
case "start": {
start = reader.nextInt();
break;
}
case "end": {
end = reader.nextInt();
break;
}
case "type": {
//noinspection ResourceType
type = reader.nextInt();
break;
}
case "width": {
width = reader.nextInt();
break;
}
case "height": {
height = reader.nextInt();
break;
}
default: {
reader.skipValue();
break;
}
}
}
}
@Override
public int describeContents() {
return 0;
@ -276,15 +296,21 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
}
@Override
public void write(Writer writer) {
writer.write("media_url", media_url);
writer.write("page_url", page_url);
writer.write("preview_url", preview_url);
writer.write("start", String.valueOf(start));
writer.write("end", String.valueOf(end));
writer.write("type", String.valueOf(type));
writer.write("width", String.valueOf(width));
writer.write("height", String.valueOf(height));
public void write(JsonWriter writer) throws IOException {
writer.beginObject();
writer.name("media_url").value(media_url);
writer.name("page_url").value(page_url);
writer.name("preview_url").value(preview_url);
writer.name("start").value(start);
writer.name("end").value(end);
writer.name("type").value(type);
writer.name("width").value(width);
writer.name("height").value(height);
if (video_info != null) {
writer.name("video_info");
video_info.write(writer);
}
writer.endObject();
}
@Override
@ -405,15 +431,11 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
}
public static class VideoInfo implements Parcelable {
public static class VideoInfo implements Parcelable, JsonReadable, JsonWritable {
public Variant[] variants;
public long[] aspect_ratio;
public long duration;
public VideoInfo(Reader source) {
}
public VideoInfo() {
@ -421,7 +443,6 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
public VideoInfo(MediaEntity.VideoInfo videoInfo) {
variants = Variant.fromMediaEntityVariants(videoInfo.getVariants());
aspect_ratio = videoInfo.getAspectRatio();
duration = videoInfo.getDuration();
}
@ -430,22 +451,76 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
return new VideoInfo(videoInfo);
}
@Override
public void read(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "variants": {
reader.beginArray();
variants = JsonSerializationUtils.array(reader, Variant.class);
reader.endArray();
break;
}
case "duration": {
duration = reader.nextLong();
break;
}
default: {
reader.skipValue();
break;
}
}
}
reader.endObject();
}
@Override
public String toString() {
return "VideoInfo{" +
"variants=" + Arrays.toString(variants) +
", aspect_ratio=" + Arrays.toString(aspect_ratio) +
", duration=" + duration +
'}';
}
public static class Variant implements Parcelable {
@Override
public void write(JsonWriter writer) {
}
public static class Variant implements Parcelable, JsonReadable {
public Variant(MediaEntity.VideoInfo.Variant entityVariant) {
content_type = entityVariant.getContentType();
url = entityVariant.getUrl();
bitrate = entityVariant.getBitrate();
}
@Override
public void read(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "content_type": {
content_type = reader.nextString();
break;
}
case "url": {
url = reader.nextString();
break;
}
case "bitrate": {
bitrate = reader.nextLong();
break;
}
default: {
reader.skipValue();
break;
}
}
}
reader.endObject();
}
@Override
public String toString() {
return "Variant{" +
@ -455,9 +530,9 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
'}';
}
public final String content_type;
public final String url;
public final long bitrate;
public String content_type;
public String url;
public long bitrate;
public Variant(JSONParcel source) {
content_type = source.readString("content_type");
@ -516,14 +591,12 @@ public class ParcelableMedia implements Parcelable, JSONParcelable, SimpleValueS
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedArray(variants, flags);
dest.writeLongArray(aspect_ratio);
dest.writeLong(duration);
}
private VideoInfo(Parcel in) {
variants = in.createTypedArray(Variant.CREATOR);
aspect_ratio = in.createLongArray();
duration = in.readLong();
}

View File

@ -33,7 +33,6 @@ import org.mariotaku.jsonserializer.JSONParcelable;
import org.mariotaku.jsonserializer.JSONSerializer;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.util.HtmlEscapeHelper;
import org.mariotaku.twidere.util.SimpleValueSerializer;
import org.mariotaku.twidere.util.TwitterContentUtils;
import java.util.Arrays;
@ -117,7 +116,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
public final ParcelableUserMention[] mentions;
public final ParcelableMedia[] media;
public final ParcelableMedia[] media, quote_media;
public final ParcelableCardEntity card;
@ -146,7 +145,8 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
retweeted_by_profile_image = idx.retweeted_by_user_profile_image != -1 ? c
.getString(idx.retweeted_by_user_profile_image) : null;
text_html = idx.text_html != -1 ? c.getString(idx.text_html) : null;
media = SimpleValueSerializer.fromSerializedString(idx.media != -1 ? c.getString(idx.media) : null, ParcelableMedia.SIMPLE_CREATOR);
media = idx.media != -1 ? ParcelableMedia.fromSerializedJson(c.getString(idx.media)) : null;
quote_media = idx.quote_media != -1 ? ParcelableMedia.fromSerializedJson(c.getString(idx.quote_media)) : null;
text_plain = idx.text_plain != -1 ? c.getString(idx.text_plain) : null;
user_name = idx.user_name != -1 ? c.getString(idx.user_name) : null;
user_screen_name = idx.user_screen_name != -1 ? c.getString(idx.user_screen_name) : null;
@ -160,7 +160,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
my_retweet_id = idx.my_retweet_id != -1 ? c.getLong(idx.my_retweet_id) : -1;
is_possibly_sensitive = idx.is_possibly_sensitive != -1 && c.getInt(idx.is_possibly_sensitive) == 1;
user_is_following = idx.is_following != -1 && c.getInt(idx.is_following) == 1;
mentions = idx.mentions != -1 ? ParcelableUserMention.fromJSONString(c.getString(idx.mentions)) : null;
mentions = idx.mentions != -1 ? ParcelableUserMention.fromSerializedJson(c.getString(idx.mentions)) : null;
card = idx.card != -1 ? ParcelableCardEntity.fromJSONString(c.getString(idx.card)) : null;
place_full_name = idx.place_full_name != -1 ? c.getString(idx.place_full_name) : null;
is_quote = idx.is_quote != -1 && c.getShort(idx.is_quote) == 1;
@ -210,6 +210,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
source = in.readString("source");
user_profile_image_url = in.readString("profile_image_url");
media = in.readParcelableArray("media", ParcelableMedia.JSON_CREATOR);
quote_media = in.readParcelableArray("quote_media", ParcelableMedia.JSON_CREATOR);
location = in.readParcelable("location", ParcelableLocation.JSON_CREATOR);
my_retweet_id = in.readLong("my_retweet_id");
is_possibly_sensitive = in.readBoolean("is_possibly_sensitive");
@ -263,6 +264,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
source = in.readString();
user_profile_image_url = in.readString();
media = in.createTypedArray(ParcelableMedia.CREATOR);
quote_media = in.createTypedArray(ParcelableMedia.CREATOR);
location = in.readParcelable(ParcelableLocation.class.getClassLoader());
my_retweet_id = in.readLong();
is_possibly_sensitive = in.readByte() == 1;
@ -319,6 +321,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
source = orig.source;
user_profile_image_url = orig.user_profile_image_url;
media = orig.media;
quote_media = orig.quote_media;
location = orig.location;
my_retweet_id = override_my_retweet_id;
is_possibly_sensitive = orig.is_possibly_sensitive;
@ -396,6 +399,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
user_is_following = user.isFollowing();
text_html = TwitterContentUtils.formatStatusText(status);
media = ParcelableMedia.fromStatus(status);
quote_media = quoted != null ? ParcelableMedia.fromStatus(orig) : null;
text_plain = status.getText();
retweet_count = status.getRetweetCount();
favorite_count = status.getFavoriteCount();
@ -539,6 +543,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
out.writeString("source", source);
out.writeString("profile_image_url", user_profile_image_url);
out.writeParcelableArray("media", media);
out.writeParcelableArray("quote_media", quote_media);
out.writeParcelable("location", location);
out.writeLong("my_retweet_id", my_retweet_id);
out.writeBoolean("is_possibly_sensitive", is_possibly_sensitive);
@ -579,10 +584,11 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
in_reply_to_user_name, in_reply_to_user_screen_name, my_retweet_id, retweeted_by_user_name,
retweeted_by_user_screen_name, retweeted_by_user_profile_image, retweet_id, retweet_timestamp,
retweeted_by_user_id, user_id, source, retweet_count, favorite_count, reply_count,
descendent_reply_count, is_possibly_sensitive, is_following, media, mentions, card_name,
card, place_full_name, is_quote, quote_id, quote_text_html, quote_text_plain, quote_text_unescaped,
quote_timestamp, quote_source, quoted_by_user_id, quoted_by_user_name, quoted_by_user_screen_name,
quoted_by_user_profile_image, quoted_by_user_is_protected, quoted_by_user_is_verified;
descendent_reply_count, is_possibly_sensitive, is_following, media, mentions, quote_media,
card_name, card, place_full_name, is_quote, quote_id, quote_text_html, quote_text_plain,
quote_text_unescaped, quote_timestamp, quote_source, quoted_by_user_id, quoted_by_user_name,
quoted_by_user_screen_name, quoted_by_user_profile_image, quoted_by_user_is_protected,
quoted_by_user_is_verified;
public CursorIndices(final Cursor cursor) {
_id = cursor.getColumnIndex(Statuses._ID);
@ -633,8 +639,9 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
descendent_reply_count = cursor.getColumnIndex(Statuses.DESCENDENT_REPLY_COUNT);
is_possibly_sensitive = cursor.getColumnIndex(Statuses.IS_POSSIBLY_SENSITIVE);
is_following = cursor.getColumnIndex(Statuses.IS_FOLLOWING);
media = cursor.getColumnIndex(Statuses.MEDIA_LIST);
mentions = cursor.getColumnIndex(Statuses.MENTIONS_LIST);
media = cursor.getColumnIndex(Statuses.MEDIA_JSON);
mentions = cursor.getColumnIndex(Statuses.MENTIONS_JSON);
quote_media = cursor.getColumnIndex(Statuses.QUOTE_MEDIA_JSON);
card = cursor.getColumnIndex(Statuses.CARD);
card_name = cursor.getColumnIndex(Statuses.CARD_NAME);
place_full_name = cursor.getColumnIndex(Statuses.PLACE_FULL_NAME);
@ -680,9 +687,23 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
", is_following=" + is_following +
", media=" + media +
", mentions=" + mentions +
", quote_media=" + quote_media +
", card_name=" + card_name +
", card=" + card +
", place_full_name=" + place_full_name +
", is_quote=" + is_quote +
", quote_id=" + quote_id +
", quote_text_html=" + quote_text_html +
", quote_text_plain=" + quote_text_plain +
", quote_text_unescaped=" + quote_text_unescaped +
", quote_timestamp=" + quote_timestamp +
", quote_source=" + quote_source +
", quoted_by_user_id=" + quoted_by_user_id +
", quoted_by_user_name=" + quoted_by_user_name +
", quoted_by_user_screen_name=" + quoted_by_user_screen_name +
", quoted_by_user_profile_image=" + quoted_by_user_profile_image +
", quoted_by_user_is_protected=" + quoted_by_user_is_protected +
", quoted_by_user_is_verified=" + quoted_by_user_is_verified +
'}';
}
@ -1054,6 +1075,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
out.writeString(source);
out.writeString(user_profile_image_url);
out.writeTypedArray(media, flags);
out.writeTypedArray(quote_media, flags);
out.writeParcelable(location, flags);
out.writeLong(my_retweet_id);
out.writeByte((byte) (is_possibly_sensitive ? 1 : 0));

View File

@ -22,22 +22,23 @@ package org.mariotaku.twidere.model;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.JsonReader;
import android.util.JsonWriter;
import org.json.JSONArray;
import org.json.JSONException;
import org.mariotaku.jsonserializer.JSONParcel;
import org.mariotaku.jsonserializer.JSONParcelable;
import org.mariotaku.jsonserializer.JSONSerializer;
import org.mariotaku.twidere.util.SimpleValueSerializer;
import org.mariotaku.twidere.util.SimpleValueSerializer.Reader;
import org.mariotaku.twidere.util.SimpleValueSerializer.SerializationException;
import org.mariotaku.twidere.util.SimpleValueSerializer.SimpleValueSerializable;
import org.mariotaku.twidere.util.SimpleValueSerializer.Writer;
import org.mariotaku.twidere.model.iface.JsonReadable;
import org.mariotaku.twidere.model.iface.JsonWritable;
import java.io.IOException;
import twitter4j.Status;
import twitter4j.UserMentionEntity;
public class ParcelableUserMention implements Parcelable, JSONParcelable, SimpleValueSerializable {
public class ParcelableUserMention implements Parcelable, JSONParcelable, JsonReadable, JsonWritable {
public static final Parcelable.Creator<ParcelableUserMention> CREATOR = new Parcelable.Creator<ParcelableUserMention>() {
@Override
@ -61,21 +62,14 @@ public class ParcelableUserMention implements Parcelable, JSONParcelable, Simple
return new ParcelableUserMention[size];
}
};
public static final SimpleValueSerializer.Creator<ParcelableUserMention> SIMPLE_CREATOR = new SimpleValueSerializer.Creator<ParcelableUserMention>() {
@Override
public ParcelableUserMention create(final SimpleValueSerializer.Reader reader) throws SerializationException {
return new ParcelableUserMention(reader);
}
@Override
public ParcelableUserMention[] newArray(final int size) {
return new ParcelableUserMention[size];
}
};
public long id;
public String name, screen_name;
public ParcelableUserMention() {
}
public ParcelableUserMention(final JSONParcel in) {
id = in.readLong("id");
name = in.readString("name");
@ -94,9 +88,39 @@ public class ParcelableUserMention implements Parcelable, JSONParcelable, Simple
screen_name = entity.getScreenName();
}
public ParcelableUserMention(Reader reader) throws SerializationException {
while (reader.hasKeyValue()) {
switch (reader.nextKey()) {
@Override
public int describeContents() {
return 0;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof ParcelableUserMention)) return false;
final ParcelableUserMention other = (ParcelableUserMention) obj;
if (id != other.id) return false;
return true;
}
public static ParcelableUserMention[] fromSerializedJson(String string) {
return new ParcelableUserMention[0];
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ id >>> 32);
return result;
}
@Override
public void read(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "id": {
id = reader.nextLong();
break;
@ -115,29 +139,7 @@ public class ParcelableUserMention implements Parcelable, JSONParcelable, Simple
}
}
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof ParcelableUserMention)) return false;
final ParcelableUserMention other = (ParcelableUserMention) obj;
if (id != other.id) return false;
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ id >>> 32);
return result;
reader.endObject();
}
@Override
@ -146,10 +148,10 @@ public class ParcelableUserMention implements Parcelable, JSONParcelable, Simple
}
@Override
public void write(Writer writer) {
writer.write("id", id);
writer.write("name", name);
writer.write("screen_name", screen_name);
public void write(JsonWriter writer) throws IOException {
writer.name("id").value(id);
writer.name("name").value(name);
writer.name("screen_name").value(screen_name);
}
@Override

View File

@ -0,0 +1,33 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.iface;
import android.util.JsonReader;
import java.io.IOException;
/**
* Created by mariotaku on 15/4/23.
*/
public interface JsonReadable {
void read(JsonReader reader) throws IOException;
}

View File

@ -0,0 +1,35 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.iface;
import android.util.JsonReader;
import android.util.JsonWriter;
import java.io.IOException;
/**
* Created by mariotaku on 15/4/23.
*/
public interface JsonWritable {
void write(JsonWriter writer) throws IOException;
}

View File

@ -336,12 +336,12 @@ public interface TwidereDataStore {
String SENDER_PROFILE_IMAGE_URL = "sender_profile_image_url";
String RECIPIENT_PROFILE_IMAGE_URL = "recipient_profile_image_url";
String MEDIA_LIST = "media_list";
String MEDIA_JSON = "media_json";
String[] COLUMNS = {_ID, ACCOUNT_ID, MESSAGE_ID, MESSAGE_TIMESTAMP,
SENDER_ID, RECIPIENT_ID, CONVERSATION_ID, IS_OUTGOING, TEXT_HTML, TEXT_PLAIN, TEXT_UNESCAPED,
SENDER_NAME, RECIPIENT_NAME, SENDER_SCREEN_NAME, RECIPIENT_SCREEN_NAME, SENDER_PROFILE_IMAGE_URL,
RECIPIENT_PROFILE_IMAGE_URL, MEDIA_LIST};
RECIPIENT_PROFILE_IMAGE_URL, MEDIA_JSON};
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT, TYPE_INT,
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT};
@ -783,9 +783,9 @@ public interface TwidereDataStore {
String MY_RETWEET_ID = "my_retweet_id";
String MEDIA_LIST = "media_list";
String MEDIA_JSON = "media_json";
String MENTIONS_LIST = "mentions_list";
String MENTIONS_JSON = "mentions_json";
String CARD = "card";
@ -821,7 +821,8 @@ public interface TwidereDataStore {
QUOTE_SOURCE, QUOTED_BY_USER_ID, QUOTED_BY_USER_NAME, QUOTED_BY_USER_SCREEN_NAME,
QUOTED_BY_USER_PROFILE_IMAGE, QUOTED_BY_USER_IS_VERIFIED, QUOTED_BY_USER_IS_PROTECTED,
MY_RETWEET_ID, IS_RETWEET, IS_QUOTE, IS_FAVORITE, IS_PROTECTED, IS_VERIFIED, IS_FOLLOWING,
IS_GAP, IS_POSSIBLY_SENSITIVE, MEDIA_LIST, MENTIONS_LIST, CARD_NAME, CARD, PLACE_FULL_NAME};
IS_GAP, IS_POSSIBLY_SENSITIVE, MEDIA_JSON, MENTIONS_JSON, QUOTE_MEDIA_JSON, CARD_NAME,
CARD, PLACE_FULL_NAME};
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT,
TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
@ -830,7 +831,7 @@ public interface TwidereDataStore {
TYPE_TEXT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_TEXT, TYPE_INT,
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_INT, TYPE_BOOLEAN,
TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN,
TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT};
TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT};
}

View File

@ -209,7 +209,7 @@ public final class ContentValuesCreator implements TwidereConstants {
values.put(DirectMessages.RECIPIENT_PROFILE_IMAGE_URL, recipient_profile_image_url);
final ParcelableMedia[] mediaArray = ParcelableMedia.fromEntities(message);
if (mediaArray != null) {
values.put(DirectMessages.MEDIA_LIST, SimpleValueSerializer.toSerializedString(mediaArray));
values.put(DirectMessages.MEDIA_JSON, JSONSerializer.toJSONArrayString(mediaArray));
}
return values;
}
@ -232,7 +232,7 @@ public final class ContentValuesCreator implements TwidereConstants {
values.put(DirectMessages.SENDER_PROFILE_IMAGE_URL, message.sender_profile_image_url);
values.put(DirectMessages.RECIPIENT_PROFILE_IMAGE_URL, message.recipient_profile_image_url);
if (message.media != null) {
values.put(DirectMessages.MEDIA_LIST, SimpleValueSerializer.toSerializedString(message.media));
values.put(DirectMessages.MEDIA_JSON, JSONSerializer.toJSONArrayString(message.media));
}
return values;
}
@ -339,7 +339,10 @@ public final class ContentValuesCreator implements TwidereConstants {
values.put(Statuses.QUOTE_TEXT_UNESCAPED, toPlainText(textHtml));
values.put(Statuses.QUOTE_TIMESTAMP, orig.getCreatedAt().getTime());
values.put(Statuses.QUOTE_SOURCE, orig.getSource());
final ParcelableMedia[] quoteMedia = ParcelableMedia.fromStatus(orig);
if (quoteMedia != null) {
values.put(Statuses.QUOTE_MEDIA_JSON, JSONSerializer.toJSONArrayString(quoteMedia));
}
values.put(Statuses.QUOTED_BY_USER_ID, quotedById);
values.put(Statuses.QUOTED_BY_USER_NAME, quoteUser.getName());
values.put(Statuses.QUOTED_BY_USER_SCREEN_NAME, quoteUser.getScreenName());
@ -395,11 +398,11 @@ public final class ContentValuesCreator implements TwidereConstants {
values.put(Statuses.IS_FAVORITE, status.isFavorited());
final ParcelableMedia[] media = ParcelableMedia.fromStatus(status);
if (media != null) {
values.put(Statuses.MEDIA_LIST, SimpleValueSerializer.toSerializedString(media));
values.put(Statuses.MEDIA_JSON, JSONSerializer.toJSONArrayString(media));
}
final ParcelableUserMention[] mentions = ParcelableUserMention.fromStatus(status);
if (mentions != null) {
values.put(Statuses.MENTIONS_LIST, SimpleValueSerializer.toSerializedString(mentions));
values.put(Statuses.MENTIONS_JSON, JSONSerializer.toJSONArrayString(mentions));
}
final ParcelableCardEntity card = ParcelableCardEntity.fromCardEntity(status.getCard(), accountId);
if (card != null) {

View File

@ -0,0 +1,66 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util;
import android.util.JsonReader;
import org.mariotaku.twidere.model.iface.JsonReadable;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
/**
* Created by mariotaku on 15/4/23.
*/
public class JsonSerializationUtils {
public static <T extends JsonReadable> T[] array(JsonReader reader, Class<T> cls) {
try {
final ArrayList<T> list = new ArrayList<>();
while (reader.hasNext()) {
final T object = cls.newInstance();
object.read(reader);
list.add(object);
}
@SuppressWarnings("unchecked")
final T[] array = (T[]) Array.newInstance(cls, list.size());
return list.toArray(array);
} catch (IOException | IllegalStateException e) {
return null;
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static <T extends JsonReadable> T object(JsonReader reader, Class<T> cls) {
try {
final T object = cls.newInstance();
object.read(reader);
return object;
} catch (IOException | IllegalStateException e) {
return null;
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,230 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.util;
import android.util.Log;
import org.mariotaku.twidere.TwidereConstants;
import java.io.IOException;
/**
* Created by mariotaku on 15/2/13.
*/
public class SimpleValueSerializer {
private static final char ESCAPE = '\\';
private static final char DIVIDER_ARRAY_ELEMENT = ';';
private static final char DIVIDER_OBJECT_FIELD = ',';
private static final char DIVIDER_KEY_VALUE = '=';
public static Reader newReader(String str) {
return new Reader(str);
}
private static <T extends SimpleValueSerializable> T[] append(T[] old, int position, T item, Creator<T> creator) {
T[] appended;
if (position < old.length) {
appended = old;
} else {
appended = creator.newArray(old.length * 2);
System.arraycopy(old, 0, appended, 0, old.length);
}
appended[position] = item;
return appended;
}
public static String escape(String str) {
final StringBuilder sb = new StringBuilder();
for (int i = 0, j = str.length(); i < j; i++) {
final char ch = str.charAt(i);
if (DIVIDER_ARRAY_ELEMENT == ch || ESCAPE == ch) {
sb.append(ESCAPE);
}
sb.append(ch);
}
return sb.toString();
}
@SafeVarargs
public static <T extends SimpleValueSerializable> String toSerializedString(T... array) {
final Writer writer = newWriter();
for (T item : array) {
writer.beginArrayElement();
item.write(writer);
}
return writer.toString();
}
public static <T extends SimpleValueSerializable> T[] fromSerializedString(final String json, Creator<T> creator) {
long start = System.nanoTime();
T[] temp = creator.newArray(4);
try {
if (json == null) return null;
final SimpleValueSerializer.Reader reader = SimpleValueSerializer.newReader(json);
int count = 0;
while (reader.hasArrayElement()) {
final T item = creator.create(reader);
reader.endArrayElement();
temp = append(temp, count++, item, creator);
}
final T[] result = creator.newArray(count);
System.arraycopy(temp, 0, result, 0, count);
return result;
} catch (final IOException e) {
e.printStackTrace();
return null;
}
}
public interface Creator<T extends SimpleValueSerializable> {
T create(Reader reader) throws SerializationException;
T[] newArray(int size);
}
public static class SerializationException extends IOException {
}
public static Writer newWriter() {
return new Writer();
}
public static interface SimpleValueSerializable {
void write(Writer writer);
}
public static class Writer {
private int keyValuesCount;
private final StringBuilder stringBuilder;
public Writer() {
stringBuilder = new StringBuilder();
keyValuesCount = 0;
}
public void beginArrayElement() {
keyValuesCount = 0;
if (stringBuilder.length() > 0) {
stringBuilder.append(DIVIDER_ARRAY_ELEMENT);
}
}
public void write(String key, String value) {
if (keyValuesCount++ > 0) {
stringBuilder.append(DIVIDER_OBJECT_FIELD);
}
stringBuilder.append(escape(key));
stringBuilder.append(DIVIDER_KEY_VALUE);
stringBuilder.append(escape(value));
}
public String toString() {
return stringBuilder.toString();
}
public void write(String key, long value) {
write(key, String.valueOf(value));
}
public void write(String key, boolean value) {
write(key, String.valueOf(value));
}
}
public static class Reader {
private final String s;
private final int len;
private char lastToken;
private int cur;
public Reader(String s) {
this.s = s;
this.len = s.length();
cur = 0;
lastToken = '\0';
}
public boolean hasKeyValue() {
return (cur == 0 || (lastToken == '\0' || lastToken == DIVIDER_OBJECT_FIELD)) && cur < len;
}
public boolean hasArrayElement() {
return (cur == 0 || (lastToken == '\0' || lastToken == DIVIDER_ARRAY_ELEMENT)) && cur < len;
}
public String nextKey() throws SerializationException {
if (lastToken != '\0' && lastToken != DIVIDER_OBJECT_FIELD) {
throw new SerializationException();
}
return peek();
}
private String peek() {
StringBuilder sb = new StringBuilder();
boolean isEscaped = false;
while (cur < len) {
char ch = s.charAt(cur++);
if (isEscaped) {
sb.append(ch);
isEscaped = false;
} else if (ch == ESCAPE) {
isEscaped = true;
} else if (ch == DIVIDER_KEY_VALUE || ch == DIVIDER_OBJECT_FIELD || ch == DIVIDER_ARRAY_ELEMENT) {
lastToken = ch;
break;
} else {
sb.append(ch);
}
}
return sb.toString();
}
public void skipValue() throws SerializationException {
nextString();
}
public String nextString() throws SerializationException {
if (lastToken != DIVIDER_KEY_VALUE) {
throw new SerializationException();
}
return peek();
}
public int nextInt() throws SerializationException {
return Integer.parseInt(nextString());
}
public long nextLong() throws SerializationException {
return Long.parseLong(nextString());
}
public void endArrayElement() {
lastToken = '\0';
}
}
}

View File

@ -33,7 +33,7 @@ import static org.mariotaku.twidere.annotation.Preference.Type.STRING;
public interface Constants extends TwidereConstants {
String DATABASES_NAME = "twidere.sqlite";
int DATABASES_VERSION = 97;
int DATABASES_VERSION = 98;
int MENU_GROUP_STATUS_EXTENSION = 10;
int MENU_GROUP_COMPOSE_EXTENSION = 11;

View File

@ -34,13 +34,12 @@ import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.MessageConversationAdapter;
import org.mariotaku.twidere.model.ParcelableDirectMessage.CursorIndices;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SimpleValueSerializer;
import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener;
import org.mariotaku.twidere.view.CardMediaContainer;
import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener;
public class MessageConversationViewHolder extends ViewHolder implements OnMediaClickListener {
@ -79,7 +78,7 @@ public class MessageConversationViewHolder extends ViewHolder implements OnMedia
final long accountId = cursor.getLong(indices.account_id);
final long timestamp = cursor.getLong(indices.message_timestamp);
final ParcelableMedia[] media = SimpleValueSerializer.fromSerializedString(cursor.getString(indices.media), ParcelableMedia.SIMPLE_CREATOR);
final ParcelableMedia[] media = ParcelableMedia.fromSerializedJson(cursor.getString(indices.media));
text.setText(Html.fromHtml(cursor.getString(indices.text)));
linkify.applyAllLinks(text, accountId, false);
text.setMovementMethod(null);

View File

@ -28,7 +28,6 @@ import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.MediaLoadingHandler;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.SimpleValueSerializer;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwitterCardUtils;
import org.mariotaku.twidere.util.UserColorNameUtils;
@ -345,10 +344,8 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi
final boolean sensitive = cursor.getShort(indices.is_possibly_sensitive) == 1;
final ParcelableMedia[] media = SimpleValueSerializer.fromSerializedString(
cursor.getString(indices.media), ParcelableMedia.SIMPLE_CREATOR);
final ParcelableLocation location = ParcelableLocation.fromString(
cursor.getString(indices.location));
final ParcelableMedia[] media = ParcelableMedia.fromSerializedJson(cursor.getString(indices.media));
final ParcelableLocation location = ParcelableLocation.fromString(cursor.getString(indices.location));
if (retweet_id > 0) {
final long retweeted_by_id = cursor.getLong(indices.retweeted_by_user_id);