delphi+FPC一个纯key-value二进制存储
<p>delphi+FPC一个纯key-value二进制存储</p><p>适用于DELPHI和FPC。</p>
<p>众所周知,JSON就是典型的key-value存储。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">咏南</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> ,
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">url</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">www.咏南中间件.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
}</span></pre>
</div>
<p>笔者弄了一个DELPHIkey-value二进制存储。</p>
<p>可用于数据序列/还原、缓存数据,方法参数传递。。。</p>
<div class="cnblogs_code">
<pre>TSerialize = <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
fValue: TBytes;
fKey: rawbytestring;
fList: tlist;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
procedure setInt(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: integer);
procedure setStr(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: rawbytestring);
procedure setVariant(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: variant);
procedure setBytes(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: TBytes);
procedure setDateTime(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: TDateTime);
procedure setBool(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: boolean);
procedure setSingle(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: single);
procedure setDouble(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span> Value: <span style="color: rgba(0, 0, 255, 1)">double</span><span style="color: rgba(0, 0, 0, 1)">);
procedure setByte(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span> Value: <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">);
procedure setInt64(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: int64);
procedure setCurrency(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: Currency);
procedure setStream(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: tstream);
procedure setWord(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: word);
procedure setExtended(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: Extended);
procedure setLongWord(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: LongWord);
procedure setShortint(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: Shortint);
procedure setSmallint(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: Smallint);
procedure setBCD(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> Value: tbcd);
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
function getInt(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): integer;
function getStr(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): rawbytestring;
function getVariant(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): variant;
function getBytes(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): TBytes;
function getDateTime(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): TDateTime;
function getBool(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): boolean;
function getSingle(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): single;
function getDouble(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring): <span style="color: rgba(0, 0, 255, 1)">double</span><span style="color: rgba(0, 0, 0, 1)">;
function getByte(</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring): <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
function getInt64(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): int64;
function getCurrency(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): Currency;
function getStream(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): tstream;
function getWord(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): word;
function getExtended(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): Extended;
function getLongWord(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): LongWord;
function getShortint(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): Shortint;
function getSmallint(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): Smallint;
function getBCD(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): tbcd;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
function getCount: integer;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
constructor Create;
destructor Destroy; </span><span style="color: rgba(0, 0, 255, 1)">override</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
function key(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): TSerialize;
procedure Clear;
function Delete(</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring): boolean;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
procedure marshal(stream: TStream);
function marshal2: TBytes;
function marshal3: RawByteString;
function marshal5: OleVariant;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
procedure unMarshal(stream: TStream); overload;
procedure unMarshal(bytes: TBytes); overload;
procedure unMarshal(raw: RawByteString); overload;
procedure unMarshal(ole: OleVariant); overload;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
property asInt[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: integer read getInt write setInt;
property asStr[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: rawbytestring read getStr write setStr;
property AsVariant[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: variant read getVariant write setVariant;
property asBytes[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: TBytes read getBytes write setBytes;
property AsDateTime[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: TDateTime read getDateTime write setDateTime;
property asBool[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: boolean read getBool write setBool;
property asSingle[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: single read getSingle write setSingle;
property asDouble[</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring]: <span style="color: rgba(0, 0, 255, 1)">double</span><span style="color: rgba(0, 0, 0, 1)"> read getDouble write setDouble;
property asByte[</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring]: <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)"> read getByte write setByte;
property asInt64[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: int64 read getInt64 write setInt64;
property asCurrency[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: Currency read getCurrency write setCurrency;
property asStream[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: tstream read getStream write setStream;
property asWord[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: word read getword write setword;
property asExtended[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: Extended read getExtended write setExtended;
property asLongWord[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: LongWord read getLongWord write setLongWord;
property asShortint[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: Shortint read getShortint write setShortint;
property asSmallint[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: Smallint read getSmallint write setSmallint;
property asBCD[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: tbcd read getBCD write setBCD;
property asFloat[</span><span style="color: rgba(0, 0, 255, 1)">const</span> keyName: rawbytestring]: <span style="color: rgba(0, 0, 255, 1)">double</span><span style="color: rgba(0, 0, 0, 1)"> read getDouble write setDouble;
property asCardinal[</span><span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> keyName: rawbytestring]: LongWord read getLongWord write setLongWord;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
property Count: integer read getCount;
end;</span></pre>
</div>
<p>例子:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">procedure TFuncBin.snowflakeID(req, res: TSerialize);
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
sf: tsnowflakeID;
begin
sf :</span>=<span style="color: rgba(0, 0, 0, 1)"> tsnowflakeID.Create;
</span><span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
sf.DatacenterId :</span>= req.asByte[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">datacenterid</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
sf.WorkerID :</span>= req.asByte[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">workerid</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
res.asInt[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 128, 1)">200</span><span style="color: rgba(0, 0, 0, 1)">;
res.asStr[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">message</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">success</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
res.asInt64[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">snowflakeid</span><span style="color: rgba(128, 0, 0, 1)">'</span>] :=<span style="color: rgba(0, 0, 0, 1)"> sf.NextId;
except
on E: Exception </span><span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
begin
res.asInt[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 128, 1)">500</span><span style="color: rgba(0, 0, 0, 1)">;
res.asStr[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">message</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">fail</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
res.asStr[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">exception</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">bin.func.snowflakeID()</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> e.Message;
WriteLog(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">bin.func.snowflakeID()</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> e.Message);
end;
end;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
sf.Free;
end;
end;</span></pre>
</div>
<div class="cnblogs_code">
<pre>procedure TFuncBin.<span style="color: rgba(0, 0, 255, 1)">select</span><span style="color: rgba(0, 0, 0, 1)">(req, res: TSerialize);
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
db: tdb;
pool: tdbpool;
i: Integer;
begin
</span><span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
pool :</span>= GetDBPool(req.asStr[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">dbid</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]);
db :</span>=<span style="color: rgba(0, 0, 0, 1)"> pool.Lock;
db.dsp.DataSet :</span>=<span style="color: rgba(0, 0, 0, 1)"> db.qry;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> i := <span style="color: rgba(128, 0, 128, 1)">1</span> to req.asByte[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">cnt</span><span style="color: rgba(128, 0, 0, 1)">'</span>] <span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
begin
db.qry.Close;
db.qry.SQL.Clear;
db.qry.SQL.Text :</span>= req.asStr[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">sql</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> i.tostring];
res.AsVariant[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ds</span><span style="color: rgba(128, 0, 0, 1)">'</span> + i.ToString] :=<span style="color: rgba(0, 0, 0, 1)"> db.dsp.Data;
end;
res.asInt[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 128, 1)">200</span><span style="color: rgba(0, 0, 0, 1)">;
res.asStr[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">message</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">success</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
except
on E: Exception </span><span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
begin
res.asInt[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 128, 1)">500</span><span style="color: rgba(0, 0, 0, 1)">;
res.asStr[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">message</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">fail</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
res.asStr[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">exception</span><span style="color: rgba(128, 0, 0, 1)">'</span>] := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">bin.func.select()</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> e.Message
end;
end;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
pool.Unlock(db);
end;
end;</span></pre>
</div>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
<p>本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/17088663.html</p><br><br>
来源:https://www.cnblogs.com/hnxxcxg/p/17088663.html
頁:
[1]