📄 lumaqqmessagemanager.java
字号:
/**
* 找到不大于今天月份的日期项偏移
* @param beginOffset
* @return
* @throws IOException
*/
private int findMonth(int beginOffset) throws IOException {
int prevOffset = 0;
while(beginOffset != 0) {
readYMD(beginOffset);
if(compareTodayWithSearchDay() <= 0)
break;
prevOffset = beginOffset;
beginOffset = getNextMonthOffset(beginOffset);
}
return prevOffset;
}
/**
* 找到不大于今天的日期项偏移
* @param beginOffset
* @return
* @throws IOException
*/
private int findDay(int beginOffset) throws IOException {
int prevOffset = 0;
while(beginOffset != 0) {
readYMD(beginOffset);
if(compareTodayWithSearchDay() <= 0)
break;
prevOffset = beginOffset;
beginOffset = getNextDayOffset(beginOffset);
}
return prevOffset;
}
/**
* 写入今天日月年,但是没有修改各项参数
* @return 新日期记录项的偏移
* @throws IOException
*/
private int writeToday() throws IOException {
int len = (int)msgFile.length();
msgFile.seek(len);
// 写入年月日
msgFile.writeChar((char)todayYear);
msgFile.writeByte((byte)todayMonth);
msgFile.writeByte((byte)todayDay);
// 写入下一段偏移
msgFile.writeInt(0);
// 写入下一天偏移
msgFile.writeInt(0);
// 写入下一月偏移
msgFile.writeInt(0);
// 写入下一年偏移
msgFile.writeInt(0);
// 本天的消息数
msgFile.writeInt(0);
return len;
}
/**
* 修改最后一天偏移
* @param offset
* @throws IOException
*/
private void setLastDayOffset(int offset) throws IOException {
msgFile.seek(6);
msgFile.writeInt(offset);
lastDayOffset = offset;
}
/**
* 修改第一天偏移
* @param offset
* @throws IOException
*/
private void setFirstDayOffset(int offset) throws IOException {
msgFile.seek(2);
msgFile.writeInt(offset);
firstDayOffset = offset;
}
/**
* 设置好友的最后一条消息偏移字段
* @param fe
* @param lastOffset
* @throws IOException
*/
private void setFriendLastOffset(FriendEntry fe, int lastOffset) throws IOException {
fe.lastOffset = lastOffset;
msgFile.seek(fe.offset + 8);
msgFile.writeInt(lastOffset);
}
/**
* 设置好友的第一条消息偏移字段
* @param fe
* @param firstOffset
* @throws IOException
*/
private void setFriendFirstOffset(FriendEntry fe, int firstOffset) throws IOException {
msgFile.seek(fe.offset + 4);
fe.firstOffset = firstOffset;
msgFile.writeInt(firstOffset);
}
/**
* 修改日期项中的消息数字段
* @param offset
* @param number
* @throws IOException
*/
private void setMessageNumber(int offset, int number) throws IOException {
msgFile.seek(offset + 20);
msgFile.writeInt(number);
}
/**
* 得到日期项中的消息数字段
* @param offset
* @return
* @throws IOException
*/
private int getMessageNumber(int offset) throws IOException {
msgFile.seek(offset + 20);
return msgFile.readInt();
}
/**
* 得到下一年的偏移
* @param offset
* @return
* @throws IOException
*/
private int getNextYearOffset(int offset) throws IOException {
msgFile.seek(offset + 16);
return msgFile.readInt();
}
/**
* 得到下一月的偏移
* @param offset
* @return
* @throws IOException
*/
private int getNextMonthOffset(int offset) throws IOException {
msgFile.seek(offset + 12);
return msgFile.readInt();
}
/**
* 得到下一天的偏移
* @param offset
* @return
* @throws IOException
*/
private int getNextDayOffset(int offset) throws IOException {
msgFile.seek(offset + 8);
return msgFile.readInt();
}
/**
* 得到下一段的偏移
* @param offset
* @return
* @throws IOException
*/
private int getNextSegmentOffset(int offset) throws IOException {
msgFile.seek(offset + 4);
return msgFile.readInt();
}
/**
* 设置下一年的偏移
* @param offset
* @param yearOffset
* @throws IOException
*/
private void setNextYearOffset(int offset, int yearOffset) throws IOException {
msgFile.seek(offset + 16);
msgFile.writeInt(yearOffset);
}
/**
* 设置下一月的偏移
* @param offset
* @param monthOffset
* @throws IOException
*/
private void setNextMonthOffset(int offset, int monthOffset) throws IOException {
msgFile.seek(offset + 12);
msgFile.writeInt(monthOffset);
}
/**
* 设置下一天的偏移
* @param offset
* @param dayOffset
* @throws IOException
*/
private void setNextDayOffset(int offset, int dayOffset) throws IOException {
msgFile.seek(offset + 8);
msgFile.writeInt(dayOffset);
}
/**
* 设置下一段的偏移
* @param offset
* @param segmentOffset
* @throws IOException
*/
private void setNextSegmentOffset(int offset, int segmentOffset) throws IOException {
msgFile.seek(offset + 4);
msgFile.writeInt(segmentOffset);
}
/**
* 得到今天的年月日,保存在成员变量year, month, day中
*/
private void getToday() {
Calendar calendar = Calendar.getInstance();
todayYear = calendar.get(Calendar.YEAR);
todayMonth = calendar.get(Calendar.MONTH) + 1; // 因为月份是从0开始的
todayDay = calendar.get(Calendar.DAY_OF_MONTH);
}
/**
* 读取日月年,保存到成员变量中
*/
private void readYMD(int offset) {
try {
msgFile.seek(offset);
searchYear = msgFile.readChar();
searchMonth = msgFile.readByte();
searchDay = msgFile.readByte();
} catch (IOException e) {
log.error(e.getMessage());
}
}
/**
* 得到年
* @param offset
* @return
* @throws IOException
*/
private int getYear(int offset) throws IOException {
msgFile.seek(offset);
return msgFile.readChar();
}
/**
* 得到月
* @param offset
* @return
* @throws IOException
*/
private int getMonth(int offset) throws IOException {
msgFile.seek(offset + 2);
return msgFile.readByte();
}
/**
* 得到日
* @param offset
* @return
* @throws IOException
*/
private int getDay(int offset) throws IOException {
msgFile.seek(offset);
return msgFile.readByte();
}
/**
* 比较今天和最近一天的日期
* @return 如果今天大于最近一天,返回1,等于返回1,小于返回-1
*/
private int compareTodayWithLastDay() {
if(todayYear != lastYear)
return (todayYear > lastYear) ? 1 : -1;
else if(todayMonth != lastMonth)
return (todayMonth > lastMonth) ? 1 : -1;
else if(todayDay != lastDay)
return (todayDay > lastDay) ? 1 : -1;
else
return 0;
}
/**
* 比较今天和当前搜索的日期
* @return 如果今天大于最近一天,返回1,等于返回1,小于返回-1
*/
private int compareTodayWithSearchDay() {
if(todayYear != searchYear)
return (todayYear > searchYear) ? 1 : -1;
else if(todayMonth != searchMonth)
return (todayMonth > searchMonth) ? 1 : -1;
else if(todayDay != searchDay)
return (todayDay > searchDay) ? 1 : -1;
else
return 0;
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.IMessage#getMessages(int, int, int, int)
*/
public List getMessages(int qqNum, int year, int month, int day) {
List ret = new ArrayList();
try {
int offset = findYMDEntry(year, month, day);
while(offset != 0) {
ret.addAll(readAllMessageEntry(offset, qqNum));
offset = getNextSegmentOffset(offset);
}
} catch (IOException e) {
log.error(e.getMessage());
}
return ret;
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.IMessage#getMessages(int)
*/
public List getMessages(int qqNum) {
// 如果不存在这个好友的记录,直接返回空列表
List ret = new ArrayList();
Integer key = new Integer(qqNum);
if(!friendHash.containsKey(key)) return ret;
try {
// 如果存在,从第一条记录开始搜索
int offset = ((FriendEntry)friendHash.get(key)).firstOffset;
while(offset != 0) {
MessageEntry me = readMessageEntry(offset, qqNum);
if(me != null)
ret.add(me);
offset = getNextMessageOffset(offset);
}
} catch (IOException e) {
log.error(e.getMessage());
}
return ret;
}
/**
* 读取一个日期项中的某个好友的所有消息项
* @param offset 日期项偏移
* @param qqNum 好友的QQ号
* @return
*/
private List readAllMessageEntry(int offset, int qqNum) throws IOException {
List ret = new ArrayList();
int num = getMessageNumber(offset);
offset += DATE_ENTRY_LENGTH;
for(int i = 0; i < num; i++) {
MessageEntry me = readMessageEntry(offset, qqNum);
if(me != null)
ret.add(me);
offset = (int)msgFile.getFilePointer();
}
return ret;
}
/**
* 读取某个好友的消息项,如果offset指定的消息项不属于这个好友,返回null
* @param offset
* @param qqNum
*/
private MessageEntry readMessageEntry(int offset, int qqNum) throws IOException {
// 判断QQ号是否相符
msgFile.seek(offset);
if(qqNum != msgFile.readInt()) {
msgFile.skipBytes(16);
msgFile.readUTF();
return null;
}
// 设置记录从属
MessageEntry entry = new MessageEntry();
entry.setOwner(qqNum);
// 读取第二级从属
entry.setSource(msgFile.readInt());
// 读取第三级从属
entry.setSender(msgFile.readInt());
// 读取消息发送时间
entry.setTime(msgFile.readInt());
// 跳过下一条消息偏移字段
msgFile.skipBytes(4);
// 读取消息内容
String msg = msgFile.readUTF();
entry.setMessage(msg);
return entry;
}
/**
* 根据日月年找到日期项
* @param year
* @param month
* @param day
* @return 日期项的偏移
*/
private int findYMDEntry(int year, int month, int day) throws IOException {
int offset = firstDayOffset;
while(offset != 0) {
readYMD(offset);
if(year == searchYear) {
if(month == searchMonth) {
if(day == searchDay)
return offset;
else if(day > searchDay)
offset = getNextDayOffset(offset);
else
return 0;
} else if(month > searchMonth) {
offset = getNextMonthOffset(offset);
} else
return 0;
} else if(year > searchYear) {
offset = getNextYearOffset(offset);
} else
return 0;
}
return 0;
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.IMessage#searchMessages(int, java.lang.String)
*/
public List searchMessages(int qqNum, String keyword) {
// 如果不存在这个好友的记录,直接返回空列表
List ret = new ArrayList();
Integer key = new Integer(qqNum);
if(!friendHash.containsKey(key)) return ret;
try {
// 如果存在,从第一条记录开始搜索
int offset = ((FriendEntry)friendHash.get(key)).firstOffset;
while(offset != 0) {
MessageEntry me = readMessageEntry(offset, qqNum);
if(me != null && me.getMessage().indexOf(keyword) != -1)
ret.add(me);
offset = getNextMessageOffset(offset);
}
} catch (IOException e) {
log.error(e.getMessage());
}
return ret;
}
/* (non-Javadoc)
* @see edu.tsinghua.lumaqq.IMessage#searchMessages(int, java.lang.String, int, int, int, int, int, int)
*/
public List searchMessages(int qqNum, String keyword, int fromYear,
int fromMonth, int fromDay, int toYear, int toMonth, int toDay) {
return null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -