Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lDEVinux
GitHub Repository: lDEVinux/eaglercraft
Path: blob/main/src/lwjgl/java/tritonus/TCircularBuffer.java
8642 views
1
/*
2
* TCircularBuffer.java
3
*
4
* This file is part of Tritonus: http://www.tritonus.org/
5
*/
6
7
/*
8
* Copyright (c) 1999 by Matthias Pfisterer
9
* Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/)
10
*
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU Library General Public License as published
13
* by the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
15
*
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU Library General Public License for more details.
20
*
21
* You should have received a copy of the GNU Library General Public
22
* License along with this program; if not, write to the Free Software
23
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
*
25
*/
26
27
package tritonus;
28
29
public class TCircularBuffer
30
{
31
private boolean m_bBlockingRead;
32
private boolean m_bBlockingWrite;
33
private byte[] m_abData;
34
private int m_nSize;
35
private long m_lReadPos;
36
private long m_lWritePos;
37
private Trigger m_trigger;
38
private boolean m_bOpen;
39
40
public TCircularBuffer(int nSize, boolean bBlockingRead, boolean bBlockingWrite, Trigger trigger)
41
{
42
m_bBlockingRead = bBlockingRead;
43
m_bBlockingWrite = bBlockingWrite;
44
m_nSize = nSize;
45
m_abData = new byte[m_nSize];
46
m_lReadPos = 0;
47
m_lWritePos = 0;
48
m_trigger = trigger;
49
m_bOpen = true;
50
}
51
52
public void close()
53
{
54
m_bOpen = false;
55
// TODO: call notify() ?
56
}
57
58
private boolean isOpen()
59
{
60
return m_bOpen;
61
}
62
63
public int availableRead()
64
{
65
return (int) (m_lWritePos - m_lReadPos);
66
}
67
68
public int availableWrite()
69
{
70
return m_nSize - availableRead();
71
}
72
73
private int getReadPos()
74
{
75
return (int) (m_lReadPos % m_nSize);
76
}
77
78
private int getWritePos()
79
{
80
return (int) (m_lWritePos % m_nSize);
81
}
82
83
public int read(byte[] abData)
84
{
85
return read(abData, 0, abData.length);
86
}
87
88
public int read(byte[] abData, int nOffset, int nLength)
89
{
90
91
if(!isOpen())
92
{
93
if(availableRead() > 0)
94
{
95
nLength = Math.min(nLength, availableRead());
96
97
} else
98
{
99
100
return -1;
101
}
102
}
103
synchronized(this)
104
{
105
if(m_trigger != null && availableRead() < nLength)
106
{
107
108
m_trigger.execute();
109
}
110
if(!m_bBlockingRead)
111
{
112
nLength = Math.min(availableRead(), nLength);
113
}
114
int nRemainingBytes = nLength;
115
while(nRemainingBytes > 0)
116
{
117
while(availableRead() == 0)
118
{
119
try
120
{
121
wait();
122
} catch (InterruptedException e)
123
{
124
125
}
126
}
127
int nAvailable = Math.min(availableRead(), nRemainingBytes);
128
while(nAvailable > 0)
129
{
130
int nToRead = Math.min(nAvailable, m_nSize - getReadPos());
131
System.arraycopy(m_abData, getReadPos(), abData, nOffset, nToRead);
132
m_lReadPos += nToRead;
133
nOffset += nToRead;
134
nAvailable -= nToRead;
135
nRemainingBytes -= nToRead;
136
}
137
notifyAll();
138
}
139
140
return nLength;
141
}
142
}
143
144
public int write(byte[] abData)
145
{
146
return write(abData, 0, abData.length);
147
}
148
149
public int write(byte[] abData, int nOffset, int nLength)
150
{
151
152
synchronized(this)
153
{
154
155
if(!m_bBlockingWrite)
156
{
157
nLength = Math.min(availableWrite(), nLength);
158
}
159
int nRemainingBytes = nLength;
160
while(nRemainingBytes > 0)
161
{
162
while(availableWrite() == 0)
163
{
164
try
165
{
166
wait();
167
} catch (InterruptedException e)
168
{
169
170
}
171
}
172
int nAvailable = Math.min(availableWrite(), nRemainingBytes);
173
while(nAvailable > 0)
174
{
175
int nToWrite = Math.min(nAvailable, m_nSize - getWritePos());
176
// TDebug.out("src buf size= " + abData.length +
177
// ", offset = " + nOffset + ", dst buf size=" +
178
// m_abData.length + " write pos=" + getWritePos() + " len="
179
// + nToWrite);
180
System.arraycopy(abData, nOffset, m_abData, getWritePos(), nToWrite);
181
m_lWritePos += nToWrite;
182
nOffset += nToWrite;
183
nAvailable -= nToWrite;
184
nRemainingBytes -= nToWrite;
185
}
186
notifyAll();
187
}
188
189
return nLength;
190
}
191
}
192
193
public static interface Trigger
194
{
195
public void execute();
196
}
197
198
}
199
200
/*** TCircularBuffer.java ***/
201
202
203