OSDN Git Service

update libMiMic
[mimic/MiMicSDK.git] / lib / src / NyLPC_cRingBuffer.c
1 /*********************************************************************************\r
2  * PROJECT: MiMic\r
3  * --------------------------------------------------------------------------------\r
4  *\r
5  * This file is part of MiMic\r
6  * Copyright (C)2011 Ryo Iizuka\r
7  *\r
8  * MiMic is free software: you can redistribute it and/or modify\r
9  * it under the terms of the GNU Lesser General Public License as published\r
10  * by the Free Software Foundation, either version 3 of the License, or\r
11  * (at your option) any later version.\r
12  *\r
13  * This program is distributed in the hope that it will be useful,\r
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
16  * GNU General Public License for more details.\r
17  *\r
18  * You should have received a copy of the GNU Lesser General Public License\r
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
20  *\r
21  * For further information please contact.\r
22  *  http://nyatla.jp/\r
23  *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
24  *\r
25  *********************************************************************************/\r
26 #include "NyLPC_cRingBuffer.h"\r
27 \r
28 \r
29 #if NyLPC_ARCH==NyLPC_ARCH_FREERTOS\r
30 #elif NyLPC_ARCH==NyLPC_ARCH_WIN32\r
31 void NyLPC_cRingBuffer_dump(NyLPC_TcRingBuffer_t* i_inst)\r
32 {\r
33     NyLPC_TUInt8* s=((NyLPC_TUInt8*)(i_inst+1));//バッファ開始位置\r
34     int i;\r
35     if(i_inst->ro<=i_inst->wo){\r
36         for(i=0;i<i_inst->ro;i++){\r
37             printf("-- ");\r
38         }\r
39         for(i=i_inst->ro;i<i_inst->wo;i++){\r
40             printf("%02X ",*(s+i));\r
41         }\r
42         for(i=i_inst->wo;i<i_inst->bl;i++){\r
43             printf("-- ");\r
44         }\r
45     }else{\r
46         for(i=0;i<i_inst->wo;i++){\r
47             printf("%02X ",*(s+i));\r
48         }\r
49         for(i=i_inst->wo;i<i_inst->ro;i++){\r
50             printf("-- ");\r
51         }\r
52         for(i=i_inst->ro;i<i_inst->bl;i++){\r
53             printf("%02X ",*(s+i));\r
54         }\r
55     }\r
56     printf("\n");\r
57 }\r
58 #else\r
59 #endif\r
60 \r
61 void NyLPC_cRingBuffer_reset(NyLPC_TcRingBuffer_t* i_inst)\r
62 {\r
63     i_inst->ro=i_inst->wo=0;\r
64 }\r
65 \r
66 NyLPC_TInt16 NyLPC_cRingBuffer_getReadableSize(NyLPC_TcRingBuffer_t* i_inst)\r
67 {\r
68     volatile NyLPC_TUInt16 wo=(i_inst)->wo;\r
69     volatile NyLPC_TUInt16 ro=(i_inst)->ro;\r
70     if(wo>=ro)\r
71     {\r
72         return wo-ro;\r
73     }else{\r
74         return (i_inst)->bl-ro;\r
75     }\r
76 }\r
77 \r
78 NyLPC_TInt16 NyLPC_cRingBuffer_getWritableSize(const NyLPC_TcRingBuffer_t* i_inst)\r
79 {\r
80     volatile NyLPC_TUInt16 wo=(i_inst)->wo;\r
81     volatile NyLPC_TUInt16 ro=(i_inst)->ro;\r
82     if(wo>=ro){\r
83         //書込み可能サイズの計算\r
84         return i_inst->bl-(wo-ro)-1;\r
85     }else{\r
86         return ro-wo-1;\r
87     }\r
88 \r
89 }\r
90 \r
91 void NyLPC_cRingBuffer_initialize(NyLPC_TcRingBuffer_t* i_inst,void* i_buf,NyLPC_TUInt16 sizeof_buf)\r
92 {\r
93     //バッファの開始位置と終了位置の計算\r
94     i_inst->bl=sizeof_buf;\r
95     i_inst->ro=0;\r
96     i_inst->wo=0;\r
97     i_inst->buf=i_buf;\r
98 }\r
99 \r
100 int NyLPC_cRingBuffer_write(NyLPC_TcRingBuffer_t* i_inst,NyLPC_TUInt8* i_data,const int i_len)\r
101 {\r
102     NyLPC_TUInt8* s=(NyLPC_TUInt8*)i_inst->buf;\r
103     NyLPC_TUInt8* p;\r
104     NyLPC_TUInt16 wo=i_inst->wo;\r
105     NyLPC_TUInt16 ro=i_inst->ro;\r
106     NyLPC_TUInt16 wsize;//書込み可能サイズ\r
107     int l,i;\r
108     NyLPC_TUInt16 rw;\r
109 \r
110     if(wo>=ro){\r
111         //書込み可能サイズの計算\r
112         wsize=i_inst->bl-(wo-ro)-1;\r
113         if(wsize<1){\r
114             return 0;\r
115         }\r
116         //書込みサイズの調整\r
117         if(wsize>i_len){\r
118             wsize=i_len;\r
119         }\r
120         //右側の書込みサイズの計算\r
121         rw=i_inst->bl-wo;\r
122         l=(wsize<rw)?wsize:rw;\r
123         //書込みポインタを設定\r
124         p=(s+wo);\r
125         for(i=l-1;i>=0;i--){\r
126             *(p++)=*(i_data++);\r
127         }\r
128         //書込み位置の調整\r
129         wo=(wo+l)%i_inst->bl;\r
130         l=wsize-l;//lに左側の書込みサイズストア\r
131     }else{\r
132         wsize=ro-wo-1;\r
133         if(wsize>i_len){\r
134             wsize=i_len;\r
135         }\r
136         l=wsize;\r
137     }\r
138     if(l>0){\r
139         //左側の書込み\r
140         p=(s+wo);\r
141         for(i=l-1;i>=0;i--){\r
142             *(p++)=*(i_data++);\r
143         }\r
144         wo+=l;\r
145     }\r
146     i_inst->wo=wo;\r
147     return wsize;\r
148 }\r
149 //読出しポインタを得る。\r
150 NyLPC_TUInt8* NyLPC_cRingBuffer_pread(NyLPC_TcRingBuffer_t* i_inst,NyLPC_TUInt16 *len)\r
151 {\r
152     NyLPC_TUInt16 ro=i_inst->ro;\r
153     *len=NyLPC_cRingBuffer_getReadableSize(i_inst);\r
154     return ((NyLPC_TUInt8*)(i_inst->buf))+ro;\r
155 }\r
156 \r
157 //前方シークする。\r
158 void NyLPC_cRingBuffer_preadSeek(NyLPC_TcRingBuffer_t* i_inst,NyLPC_TUInt16 i_seek)\r
159 {\r
160     NyLPC_Assert(NyLPC_cRingBuffer_getReadableSize(i_inst)>=i_seek);\r
161     i_inst->ro=(i_inst->ro+i_seek)%i_inst->bl;\r
162 }\r
163 \r
164 #define TEST\r
165 #ifndef TEST\r
166 void main(void)\r
167 {\r
168     NyLPC_TUInt16 l;\r
169     NyLPC_TUInt8* b;\r
170     int c;\r
171     char buf[sizeof(NyLPC_TcRingBuffer_t)+5];\r
172     NyLPC_TcRingBuffer_t* s;\r
173     s=NyLPC_cRingBuffer_initialize(buf,sizeof(buf));\r
174     for(;;){\r
175         b=NyLPC_cRingBuffer_getReadPtr(s,&l);\r
176         printf("readable:%d\n",l);\r
177         c=NyLPC_cRingBuffer_write(s,"0123456789",3);\r
178         NyLPC_cRingBuffer_dump(s);\r
179         b=NyLPC_cRingBuffer_getReadPtr(s,&l);\r
180         printf("readable:%d\n",l);\r
181         NyLPC_cRingBuffer_seekReadPtr(s,(l>1)?l-1:1);\r
182         printf("read:%d\n",(l>1)?l-1:1);\r
183         NyLPC_cRingBuffer_dump(s);\r
184     }\r
185 \r
186 }\r
187 #endif\r