parent
577b3d2546
commit
efdfb62282
@ -0,0 +1,47 @@ |
|||||||
|
package com.arialyy.aria.core.inf; |
||||||
|
|
||||||
|
import com.arialyy.aria.orm.Ignore; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2017/2/23. |
||||||
|
*/ |
||||||
|
|
||||||
|
public interface IEntity { |
||||||
|
/** |
||||||
|
* 其它状态 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_OTHER = -1; |
||||||
|
/** |
||||||
|
* 失败状态 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_FAIL = 0; |
||||||
|
/** |
||||||
|
* 完成状态 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_COMPLETE = 1; |
||||||
|
/** |
||||||
|
* 停止状态 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_STOP = 2; |
||||||
|
/** |
||||||
|
* 未开始状态 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_WAIT = 3; |
||||||
|
/** |
||||||
|
* 下载中 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_RUNNING = 4; |
||||||
|
/** |
||||||
|
* 预处理 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_PRE = 5; |
||||||
|
/** |
||||||
|
* 预处理完成 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_POST_PRE = 6; |
||||||
|
/** |
||||||
|
* 取消下载 |
||||||
|
*/ |
||||||
|
@Ignore public static final int STATE_CANCEL = 7; |
||||||
|
|
||||||
|
} |
@ -1,8 +1,9 @@ |
|||||||
package com.arialyy.aria.core.inf; |
package com.arialyy.aria.core.inf; |
||||||
|
|
||||||
/** |
/** |
||||||
* Created by Aria.Lao on 2017/2/13. |
* Created by Aria.Lao on 2017/2/23. |
||||||
*/ |
*/ |
||||||
|
|
||||||
public interface ITaskEntity { |
public interface ITaskEntity { |
||||||
|
|
||||||
} |
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.arialyy.aria.core.queue; |
||||||
|
|
||||||
|
import com.arialyy.aria.core.download.DownloadTask; |
||||||
|
import com.arialyy.aria.core.inf.IEntity; |
||||||
|
import com.arialyy.aria.core.inf.ITask; |
||||||
|
import com.arialyy.aria.core.inf.ITaskEntity; |
||||||
|
import com.arialyy.aria.core.queue.pool.CachePool; |
||||||
|
import com.arialyy.aria.core.queue.pool.ExecutePool; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2017/2/23. |
||||||
|
*/ |
||||||
|
abstract class AbsTaskQueue<TASK extends ITask, TASK_ENTITY extends ITaskEntity, ENTITY extends IEntity> |
||||||
|
implements ITaskQueue<TASK, TASK_ENTITY, ENTITY> { |
||||||
|
CachePool<DownloadTask> mCachePool = new CachePool<>(); |
||||||
|
ExecutePool<DownloadTask> mExecutePool = new ExecutePool<>(); |
||||||
|
} |
@ -1,54 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
|
|
||||||
package com.arialyy.aria.core.queue; |
|
||||||
|
|
||||||
import com.arialyy.aria.core.task.DownloadTask; |
|
||||||
|
|
||||||
/** |
|
||||||
* Created by lyy on 2016/8/16. |
|
||||||
* 下载功能接口 |
|
||||||
*/ |
|
||||||
public interface IDownloader { |
|
||||||
/** |
|
||||||
* 开始任务 |
|
||||||
* |
|
||||||
* @param task {@link DownloadTask} |
|
||||||
*/ |
|
||||||
public void startTask(DownloadTask task); |
|
||||||
|
|
||||||
/** |
|
||||||
* 停止任务 |
|
||||||
* |
|
||||||
* @param task {@link DownloadTask} |
|
||||||
*/ |
|
||||||
public void stopTask(DownloadTask task); |
|
||||||
|
|
||||||
/** |
|
||||||
* 取消任务 |
|
||||||
* |
|
||||||
* @param task {@link DownloadTask} |
|
||||||
*/ |
|
||||||
public void cancelTask(DownloadTask task); |
|
||||||
|
|
||||||
/** |
|
||||||
* 重试下载 |
|
||||||
* |
|
||||||
* @param task {@link DownloadTask} |
|
||||||
*/ |
|
||||||
public void reTryStart(DownloadTask task); |
|
||||||
} |
|
@ -0,0 +1,39 @@ |
|||||||
|
package com.arialyy.aria.core.upload; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2017/2/23. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class UploadListener implements IUploadListener{ |
||||||
|
@Override public void onPre() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onStart(long fileSize) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onResume(long resumeLocation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onStop(long stopLocation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onProgress(long currentLocation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onCancel() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onComplete() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onFail() { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
package com.arialyy.aria.core.upload; |
||||||
|
|
||||||
|
import android.os.Handler; |
||||||
|
import com.arialyy.aria.core.inf.IEntity; |
||||||
|
import com.arialyy.aria.core.inf.ITask; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2017/2/23. |
||||||
|
* 上传任务 |
||||||
|
*/ |
||||||
|
public class UploadTask implements ITask { |
||||||
|
private Handler mOutHandler; |
||||||
|
private UploadTaskEntity mTaskEntity; |
||||||
|
private UploadEntity mUploadEntity; |
||||||
|
|
||||||
|
UploadTask(UploadTaskEntity taskEntity, Handler outHandler) { |
||||||
|
mTaskEntity = taskEntity; |
||||||
|
mOutHandler = outHandler; |
||||||
|
mUploadEntity = mTaskEntity.uploadEntity; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public String getKey() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public boolean isRunning() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public IEntity getEntity() { |
||||||
|
return mUploadEntity; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void start() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void stop() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void cancel() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public long getSpeed() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public long getFileSize() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public long getCurrentProgress() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
private static class UListener extends UploadListener{ |
||||||
|
@Override public void onPre() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onStart(long fileSize) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onResume(long resumeLocation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onStop(long stopLocation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onProgress(long currentLocation) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onCancel() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onComplete() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void onFail() { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class Builder { |
||||||
|
private Handler mOutHandler; |
||||||
|
private UploadTaskEntity mTaskEntity; |
||||||
|
|
||||||
|
public void setOutHandler(Handler outHandler){ |
||||||
|
mOutHandler = outHandler; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUploadTaskEntity(UploadTaskEntity taskEntity){ |
||||||
|
mTaskEntity = taskEntity; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder(){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public UploadTask build(){ |
||||||
|
UploadTask task = new UploadTask(mTaskEntity, mOutHandler); |
||||||
|
return task; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
package com.arialyy.aria.core.upload; |
||||||
|
|
||||||
|
import com.arialyy.aria.core.queue.ITaskQueue; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2017/2/23. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class UploadTaskQueue implements ITaskQueue<UploadTask, UploadTaskEntity, UploadEntity>{ |
||||||
|
@Override public void startTask(UploadTask task) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void stopTask(UploadTask task) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void cancelTask(UploadTask task) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public void reTryStart(UploadTask task) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public int size() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void setDownloadNum(int downloadNum) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public UploadTask createTask(String targetName, UploadTaskEntity entity) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public UploadTask getTask(UploadEntity entity) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void removeTask(UploadEntity entity) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override public UploadTask getNextTask() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,331 @@ |
|||||||
|
/** |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arialyy.aria.util; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.FileNotFoundException; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.RandomAccessFile; |
||||||
|
import java.util.Arrays; |
||||||
|
|
||||||
|
//import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/** |
||||||
|
* A <code>BufferedRandomAccessFile</code> is like a |
||||||
|
* <code>RandomAccessFile</code>, but it uses a private buffer so that most |
||||||
|
* operations do not require a disk access. |
||||||
|
* <P> |
||||||
|
* |
||||||
|
* Note: The operations on this class are unmonitored. Also, the correct |
||||||
|
* functioning of the <code>RandomAccessFile</code> methods that are not |
||||||
|
* overridden here relies on the implementation of those methods in the |
||||||
|
* superclass. |
||||||
|
* Author : Avinash Lakshman ( alakshman@facebook.com) Prashant Malik ( pmalik@facebook.com ) |
||||||
|
*/ |
||||||
|
|
||||||
|
public final class BufferedRandomAccessFile extends RandomAccessFile { |
||||||
|
//private static final Logger logger_ = Logger.getLogger(BufferedRandomAccessFile.class);
|
||||||
|
static final int LogBuffSz_ = 16; // 64K buffer
|
||||||
|
public static final int BuffSz_ = (1 << LogBuffSz_); |
||||||
|
static final long BuffMask_ = ~(((long) BuffSz_) - 1L); |
||||||
|
|
||||||
|
/* |
||||||
|
* This implementation is based on the buffer implementation in Modula-3's |
||||||
|
* "Rd", "Wr", "RdClass", and "WrClass" interfaces. |
||||||
|
*/ |
||||||
|
private boolean dirty_; // true iff unflushed bytes exist
|
||||||
|
private boolean closed_; // true iff the file is closed
|
||||||
|
private long curr_; // current position in file
|
||||||
|
private long lo_, hi_; // bounds on characters in "buff"
|
||||||
|
private byte[] buff_; // local buffer
|
||||||
|
private long maxHi_; // this.lo + this.buff.length
|
||||||
|
private boolean hitEOF_; // buffer contains last file block?
|
||||||
|
private long diskPos_; // disk position
|
||||||
|
|
||||||
|
/* |
||||||
|
* To describe the above fields, we introduce the following abstractions for |
||||||
|
* the file "f": |
||||||
|
* |
||||||
|
* len(f) the length of the file curr(f) the current position in the file |
||||||
|
* c(f) the abstract contents of the file disk(f) the contents of f's |
||||||
|
* backing disk file closed(f) true iff the file is closed |
||||||
|
* |
||||||
|
* "curr(f)" is an index in the closed interval [0, len(f)]. "c(f)" is a |
||||||
|
* character sequence of length "len(f)". "c(f)" and "disk(f)" may differ if |
||||||
|
* "c(f)" contains unflushed writes not reflected in "disk(f)". The flush |
||||||
|
* operation has the effect of making "disk(f)" identical to "c(f)". |
||||||
|
* |
||||||
|
* A file is said to be *valid* if the following conditions hold: |
||||||
|
* |
||||||
|
* V1. The "closed" and "curr" fields are correct: |
||||||
|
* |
||||||
|
* f.closed == closed(f) f.curr == curr(f) |
||||||
|
* |
||||||
|
* V2. The current position is either contained in the buffer, or just past |
||||||
|
* the buffer: |
||||||
|
* |
||||||
|
* f.lo <= f.curr <= f.hi |
||||||
|
* |
||||||
|
* V3. Any (possibly) unflushed characters are stored in "f.buff": |
||||||
|
* |
||||||
|
* (forall i in [f.lo, f.curr): c(f)[i] == f.buff[i - f.lo]) |
||||||
|
* |
||||||
|
* V4. For all characters not covered by V3, c(f) and disk(f) agree: |
||||||
|
* |
||||||
|
* (forall i in [f.lo, len(f)): i not in [f.lo, f.curr) => c(f)[i] == |
||||||
|
* disk(f)[i]) |
||||||
|
* |
||||||
|
* V5. "f.dirty" is true iff the buffer contains bytes that should be |
||||||
|
* flushed to the file; by V3 and V4, only part of the buffer can be dirty. |
||||||
|
* |
||||||
|
* f.dirty == (exists i in [f.lo, f.curr): c(f)[i] != f.buff[i - f.lo]) |
||||||
|
* |
||||||
|
* V6. this.maxHi == this.lo + this.buff.length |
||||||
|
* |
||||||
|
* Note that "f.buff" can be "null" in a valid file, since the range of |
||||||
|
* characters in V3 is empty when "f.lo == f.curr". |
||||||
|
* |
||||||
|
* A file is said to be *ready* if the buffer contains the current position, |
||||||
|
* i.e., when: |
||||||
|
* |
||||||
|
* R1. !f.closed && f.buff != null && f.lo <= f.curr && f.curr < f.hi |
||||||
|
* |
||||||
|
* When a file is ready, reading or writing a single byte can be performed |
||||||
|
* by reading or writing the in-memory buffer without performing a disk |
||||||
|
* operation. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Open a new <code>BufferedRandomAccessFile</code> on <code>file</code> |
||||||
|
* in mode <code>mode</code>, which should be "r" for reading only, or |
||||||
|
* "rw" for reading and writing. |
||||||
|
*/ |
||||||
|
public BufferedRandomAccessFile(File file, String mode) throws IOException { |
||||||
|
super(file, mode); |
||||||
|
this.init(0); |
||||||
|
} |
||||||
|
|
||||||
|
public BufferedRandomAccessFile(File file, String mode, int size) throws IOException { |
||||||
|
super(file, mode); |
||||||
|
this.init(size); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Open a new <code>BufferedRandomAccessFile</code> on the file named |
||||||
|
* <code>name</code> in mode <code>mode</code>, which should be "r" for |
||||||
|
* reading only, or "rw" for reading and writing. |
||||||
|
*/ |
||||||
|
public BufferedRandomAccessFile(String name, String mode) throws IOException { |
||||||
|
super(name, mode); |
||||||
|
this.init(0); |
||||||
|
} |
||||||
|
|
||||||
|
public BufferedRandomAccessFile(String name, String mode, int size) throws FileNotFoundException { |
||||||
|
super(name, mode); |
||||||
|
this.init(size); |
||||||
|
} |
||||||
|
|
||||||
|
private void init(int size) { |
||||||
|
this.dirty_ = this.closed_ = false; |
||||||
|
this.lo_ = this.curr_ = this.hi_ = 0; |
||||||
|
this.buff_ = (size > BuffSz_) ? new byte[size] : new byte[BuffSz_]; |
||||||
|
this.maxHi_ = (long) BuffSz_; |
||||||
|
this.hitEOF_ = false; |
||||||
|
this.diskPos_ = 0L; |
||||||
|
} |
||||||
|
|
||||||
|
public void close() throws IOException { |
||||||
|
this.flush(); |
||||||
|
this.closed_ = true; |
||||||
|
super.close(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Flush any bytes in the file's buffer that have not yet been written to |
||||||
|
* disk. If the file was created read-only, this method is a no-op. |
||||||
|
*/ |
||||||
|
public void flush() throws IOException { |
||||||
|
this.flushBuffer(); |
||||||
|
} |
||||||
|
|
||||||
|
/* Flush any dirty bytes in the buffer to disk. */ |
||||||
|
private void flushBuffer() throws IOException { |
||||||
|
if (this.dirty_) { |
||||||
|
if (this.diskPos_ != this.lo_) super.seek(this.lo_); |
||||||
|
int len = (int) (this.curr_ - this.lo_); |
||||||
|
super.write(this.buff_, 0, len); |
||||||
|
this.diskPos_ = this.curr_; |
||||||
|
this.dirty_ = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* Read at most "this.buff.length" bytes into "this.buff", returning the |
||||||
|
* number of bytes read. If the return result is less than |
||||||
|
* "this.buff.length", then EOF was read. |
||||||
|
*/ |
||||||
|
private int fillBuffer() throws IOException { |
||||||
|
int cnt = 0; |
||||||
|
int rem = this.buff_.length; |
||||||
|
while (rem > 0) { |
||||||
|
int n = super.read(this.buff_, cnt, rem); |
||||||
|
if (n < 0) break; |
||||||
|
cnt += n; |
||||||
|
rem -= n; |
||||||
|
} |
||||||
|
if ((cnt < 0) && (this.hitEOF_ = (cnt < this.buff_.length))) { |
||||||
|
// make sure buffer that wasn't read is initialized with -1
|
||||||
|
Arrays.fill(this.buff_, cnt, this.buff_.length, (byte) 0xff); |
||||||
|
} |
||||||
|
this.diskPos_ += cnt; |
||||||
|
return cnt; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* This method positions <code>this.curr</code> at position <code>pos</code>. |
||||||
|
* If <code>pos</code> does not fall in the current buffer, it flushes the |
||||||
|
* current buffer and loads the correct one.<p> |
||||||
|
* |
||||||
|
* On exit from this routine <code>this.curr == this.hi</code> iff <code>pos</code> |
||||||
|
* is at or past the end-of-file, which can only happen if the file was |
||||||
|
* opened in read-only mode. |
||||||
|
*/ |
||||||
|
public void seek(long pos) throws IOException { |
||||||
|
if (pos >= this.hi_ || pos < this.lo_) { |
||||||
|
// seeking outside of current buffer -- flush and read
|
||||||
|
this.flushBuffer(); |
||||||
|
this.lo_ = pos & BuffMask_; // start at BuffSz boundary
|
||||||
|
this.maxHi_ = this.lo_ + (long) this.buff_.length; |
||||||
|
if (this.diskPos_ != this.lo_) { |
||||||
|
super.seek(this.lo_); |
||||||
|
this.diskPos_ = this.lo_; |
||||||
|
} |
||||||
|
int n = this.fillBuffer(); |
||||||
|
this.hi_ = this.lo_ + (long) n; |
||||||
|
} else { |
||||||
|
// seeking inside current buffer -- no read required
|
||||||
|
if (pos < this.curr_) { |
||||||
|
// if seeking backwards, we must flush to maintain V4
|
||||||
|
this.flushBuffer(); |
||||||
|
} |
||||||
|
} |
||||||
|
this.curr_ = pos; |
||||||
|
} |
||||||
|
|
||||||
|
public long getFilePointer() { |
||||||
|
return this.curr_; |
||||||
|
} |
||||||
|
|
||||||
|
public long length() throws IOException { |
||||||
|
return Math.max(this.curr_, super.length()); |
||||||
|
} |
||||||
|
|
||||||
|
public int read() throws IOException { |
||||||
|
if (this.curr_ >= this.hi_) { |
||||||
|
// test for EOF
|
||||||
|
// if (this.hi < this.maxHi) return -1;
|
||||||
|
if (this.hitEOF_) return -1; |
||||||
|
|
||||||
|
// slow path -- read another buffer
|
||||||
|
this.seek(this.curr_); |
||||||
|
if (this.curr_ == this.hi_) return -1; |
||||||
|
} |
||||||
|
byte res = this.buff_[(int) (this.curr_ - this.lo_)]; |
||||||
|
this.curr_++; |
||||||
|
return ((int) res) & 0xFF; // convert byte -> int
|
||||||
|
} |
||||||
|
|
||||||
|
public int read(byte[] b) throws IOException { |
||||||
|
return this.read(b, 0, b.length); |
||||||
|
} |
||||||
|
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException { |
||||||
|
if (this.curr_ >= this.hi_) { |
||||||
|
// test for EOF
|
||||||
|
// if (this.hi < this.maxHi) return -1;
|
||||||
|
if (this.hitEOF_) return -1; |
||||||
|
|
||||||
|
// slow path -- read another buffer
|
||||||
|
this.seek(this.curr_); |
||||||
|
if (this.curr_ == this.hi_) return -1; |
||||||
|
} |
||||||
|
len = Math.min(len, (int) (this.hi_ - this.curr_)); |
||||||
|
int buffOff = (int) (this.curr_ - this.lo_); |
||||||
|
System.arraycopy(this.buff_, buffOff, b, off, len); |
||||||
|
this.curr_ += len; |
||||||
|
return len; |
||||||
|
} |
||||||
|
|
||||||
|
public void write(int b) throws IOException { |
||||||
|
if (this.curr_ >= this.hi_) { |
||||||
|
if (this.hitEOF_ && this.hi_ < this.maxHi_) { |
||||||
|
// at EOF -- bump "hi"
|
||||||
|
this.hi_++; |
||||||
|
} else { |
||||||
|
// slow path -- write current buffer; read next one
|
||||||
|
this.seek(this.curr_); |
||||||
|
if (this.curr_ == this.hi_) { |
||||||
|
// appending to EOF -- bump "hi"
|
||||||
|
this.hi_++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
this.buff_[(int) (this.curr_ - this.lo_)] = (byte) b; |
||||||
|
this.curr_++; |
||||||
|
this.dirty_ = true; |
||||||
|
} |
||||||
|
|
||||||
|
public void write(byte[] b) throws IOException { |
||||||
|
this.write(b, 0, b.length); |
||||||
|
} |
||||||
|
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException { |
||||||
|
while (len > 0) { |
||||||
|
int n = this.writeAtMost(b, off, len); |
||||||
|
off += n; |
||||||
|
len -= n; |
||||||
|
this.dirty_ = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* Write at most "len" bytes to "b" starting at position "off", and return |
||||||
|
* the number of bytes written. |
||||||
|
*/ |
||||||
|
private int writeAtMost(byte[] b, int off, int len) throws IOException { |
||||||
|
if (this.curr_ >= this.hi_) { |
||||||
|
if (this.hitEOF_ && this.hi_ < this.maxHi_) { |
||||||
|
// at EOF -- bump "hi"
|
||||||
|
this.hi_ = this.maxHi_; |
||||||
|
} else { |
||||||
|
// slow path -- write current buffer; read next one
|
||||||
|
this.seek(this.curr_); |
||||||
|
if (this.curr_ == this.hi_) { |
||||||
|
// appending to EOF -- bump "hi"
|
||||||
|
this.hi_ = this.maxHi_; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
len = Math.min(len, (int) (this.hi_ - this.curr_)); |
||||||
|
int buffOff = (int) (this.curr_ - this.lo_); |
||||||
|
System.arraycopy(b, off, this.buff_, buffOff, len); |
||||||
|
this.curr_ += len; |
||||||
|
return len; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue