mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-08-23 18:25:50 +00:00
feat[csharp]: csharp support compatible field
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* 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.zfoo.protocol.serializer.csharp;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public class CsCharSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteChar({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateProtocolFile.index.getAndIncrement();
|
||||
|
||||
GenerateProtocolFile.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("char {} = buffer.ReadChar();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,9 @@ import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
*/
|
||||
public abstract class GenerateCsUtils {
|
||||
|
||||
private static String protocolOutputRootPath = "CsProtocol/";
|
||||
// custom configuration
|
||||
public static String protocolOutputRootPath = "zfoocs";
|
||||
public static String protocolOutputPath = StringUtils.EMPTY;
|
||||
|
||||
private static Map<ISerializer, ICsSerializer> csSerializerMap;
|
||||
|
||||
@@ -52,10 +54,13 @@ public abstract class GenerateCsUtils {
|
||||
}
|
||||
|
||||
public static void init(GenerateOperation generateOperation) {
|
||||
protocolOutputRootPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
|
||||
|
||||
FileUtils.deleteFile(new File(protocolOutputRootPath));
|
||||
FileUtils.createDirectory(protocolOutputRootPath);
|
||||
// if not specify output path, then use current default path
|
||||
if (StringUtils.isEmpty(generateOperation.getProtocolPath())) {
|
||||
protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
|
||||
} else {
|
||||
protocolOutputPath = generateOperation.getProtocolPath();
|
||||
}
|
||||
FileUtils.deleteFile(new File(protocolOutputPath));
|
||||
|
||||
csSerializerMap = new HashMap<>();
|
||||
csSerializerMap.put(BooleanSerializer.INSTANCE, new CsBooleanSerializer());
|
||||
@@ -76,6 +81,7 @@ public abstract class GenerateCsUtils {
|
||||
public static void clear() {
|
||||
csSerializerMap = null;
|
||||
protocolOutputRootPath = null;
|
||||
protocolOutputPath = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,14 +90,13 @@ public abstract class GenerateCsUtils {
|
||||
public static void createProtocolManager() throws IOException {
|
||||
var list = List.of("csharp/ProtocolManager.cs"
|
||||
, "csharp/IProtocolRegistration.cs"
|
||||
, "csharp/IProtocol.cs"
|
||||
, "csharp/Buffer/ByteBuffer.cs"
|
||||
, "csharp/Buffer/LittleEndianByteBuffer.cs"
|
||||
, "csharp/Buffer/BigEndianByteBuffer.cs");
|
||||
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
var createFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, StringUtils.substringAfterFirst(fileName, "csharp/")));
|
||||
var createFile = new File(StringUtils.format("{}/{}", protocolOutputPath, StringUtils.substringAfterFirst(fileName, "csharp/")));
|
||||
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace CsProtocol.Buffer
|
||||
namespace zfoocs
|
||||
{
|
||||
public class BigEndianByteBuffer : ByteBuffer
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Text;
|
||||
|
||||
// CSharp字节保存在内存的低地址中是根据操作系统来的,所以有可能是大端模式,也有可能是小端模式
|
||||
// 右移操作>>是带符号右移
|
||||
namespace CsProtocol.Buffer
|
||||
namespace zfoocs
|
||||
{
|
||||
public abstract class ByteBuffer
|
||||
{
|
||||
@@ -49,6 +49,30 @@ namespace CsProtocol.Buffer
|
||||
readOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void AdjustPadding(int predictionLength, int beforeWriteIndex) {
|
||||
// 因为写入的是可变长的int,如果预留的位置过多,则清除多余的位置
|
||||
var currentWriteIndex = WriteOffset();
|
||||
var predictionCount = WriteIntCount(predictionLength);
|
||||
var length = currentWriteIndex - beforeWriteIndex - predictionCount;
|
||||
var lengthCount = WriteIntCount(length);
|
||||
var padding = lengthCount - predictionCount;
|
||||
if (padding == 0) {
|
||||
SetWriteOffset(beforeWriteIndex);
|
||||
WriteInt(length);
|
||||
SetWriteOffset(currentWriteIndex);
|
||||
} else {
|
||||
var bytes = new byte[length];
|
||||
Array.Copy(buffer, currentWriteIndex - length, bytes, 0, length);
|
||||
SetWriteOffset(beforeWriteIndex);
|
||||
WriteInt(length);
|
||||
WriteBytes(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CompatibleRead(int beforeReadIndex, int length) {
|
||||
return length != -1 && ReadOffset() < length + beforeReadIndex;
|
||||
}
|
||||
|
||||
// -------------------------------------------------get/set-------------------------------------------------
|
||||
public int WriteOffset()
|
||||
@@ -69,6 +93,11 @@ namespace CsProtocol.Buffer
|
||||
writeOffset = writeIndex;
|
||||
}
|
||||
|
||||
public int ReadOffset()
|
||||
{
|
||||
return readOffset;
|
||||
}
|
||||
|
||||
public void SetReadOffset(int readIndex)
|
||||
{
|
||||
if (readIndex > writeOffset)
|
||||
@@ -235,6 +264,31 @@ namespace CsProtocol.Buffer
|
||||
|
||||
return (int) (value >> 1) ^ -((int) (value) & 1);
|
||||
}
|
||||
|
||||
public int WriteIntCount(int intValue)
|
||||
{
|
||||
// 用Zigzag算法压缩int和long的值
|
||||
// 再用Varint紧凑算法表示数字的有效位
|
||||
uint value = (uint) ((intValue << 1) ^ (intValue >> 31));
|
||||
|
||||
if (value >> 7 == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (value >> 14 == 0)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if (value >> 21 == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
if (value >> 28 == 0)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
// 写入没有压缩的int
|
||||
public abstract void WriteRawInt(int value);
|
||||
@@ -391,20 +445,6 @@ namespace CsProtocol.Buffer
|
||||
public abstract void WriteDouble(double value);
|
||||
public abstract double ReadDouble();
|
||||
|
||||
// *******************************************char***************************************************
|
||||
public char ReadChar()
|
||||
{
|
||||
// need check
|
||||
var str = ReadString();
|
||||
return string.IsNullOrEmpty(str) ? char.MinValue : str[0];
|
||||
}
|
||||
|
||||
public void WriteChar(char value)
|
||||
{
|
||||
// need check
|
||||
WriteString(new string(value, 1));
|
||||
}
|
||||
|
||||
// *******************************************String***************************************************
|
||||
|
||||
public void WriteString(string value)
|
||||
@@ -794,38 +834,6 @@ namespace CsProtocol.Buffer
|
||||
return array;
|
||||
}
|
||||
|
||||
public void WriteCharArray(char[] array)
|
||||
{
|
||||
if ((array == null) || (array.Length == 0))
|
||||
{
|
||||
WriteInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInt(array.Length);
|
||||
int length = array.Length;
|
||||
for (int index = 0; index < length; index++)
|
||||
{
|
||||
WriteChar(array[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public char[] ReadCharArray()
|
||||
{
|
||||
int size = ReadInt();
|
||||
char[] array = new char[size];
|
||||
if (size > 0)
|
||||
{
|
||||
for (int index = 0; index < size; index++)
|
||||
{
|
||||
array[index] = ReadChar();
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public void WriteStringArray(string[] array)
|
||||
{
|
||||
if ((array == null) || (array.Length == 0))
|
||||
@@ -1116,38 +1124,6 @@ namespace CsProtocol.Buffer
|
||||
return list;
|
||||
}
|
||||
|
||||
public void WriteCharList(List<char> list)
|
||||
{
|
||||
if ((list == null) || (list.Count == 0))
|
||||
{
|
||||
WriteInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInt(list.Count);
|
||||
int length = list.Count;
|
||||
for (int index = 0; index < length; index++)
|
||||
{
|
||||
WriteDouble(list[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<char> ReadCharList()
|
||||
{
|
||||
int size = ReadInt();
|
||||
List<char> list = new List<char>(size);
|
||||
if (size > 0)
|
||||
{
|
||||
for (int index = 0; index < size; index++)
|
||||
{
|
||||
list.Add(ReadChar());
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public void WriteStringList(List<string> list)
|
||||
{
|
||||
if ((list == null) || (list.Count == 0))
|
||||
@@ -1400,37 +1376,6 @@ namespace CsProtocol.Buffer
|
||||
return set;
|
||||
}
|
||||
|
||||
public void WriteCharSet(HashSet<char> set)
|
||||
{
|
||||
if ((set == null) || (set.Count == 0))
|
||||
{
|
||||
WriteInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInt(set.Count);
|
||||
foreach (var element in set)
|
||||
{
|
||||
WriteChar(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HashSet<char> ReadCharSet()
|
||||
{
|
||||
int size = ReadInt();
|
||||
HashSet<char> set = new HashSet<char>();
|
||||
if (size > 0)
|
||||
{
|
||||
for (int index = 0; index < size; index++)
|
||||
{
|
||||
set.Add(ReadChar());
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public void WriteStringSet(HashSet<string> set)
|
||||
{
|
||||
if ((set == null) || (set.Count == 0))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace CsProtocol.Buffer
|
||||
namespace zfoocs
|
||||
{
|
||||
public class LittleEndianByteBuffer : ByteBuffer
|
||||
{
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace CsProtocol.Buffer
|
||||
{
|
||||
public interface IProtocol
|
||||
{
|
||||
short ProtocolId();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace CsProtocol.Buffer
|
||||
namespace zfoocs
|
||||
{
|
||||
public interface IProtocolRegistration
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CsProtocol.Buffer;
|
||||
|
||||
namespace CsProtocol
|
||||
namespace zfoocs
|
||||
{
|
||||
public class ProtocolManager
|
||||
{
|
||||
@@ -10,33 +9,12 @@ namespace CsProtocol
|
||||
|
||||
|
||||
private static readonly IProtocolRegistration[] protocolList = new IProtocolRegistration[MAX_PROTOCOL_NUM];
|
||||
private static readonly Dictionary<Type, short> protocolIdMap = new Dictionary<Type, short>();
|
||||
|
||||
|
||||
public static void InitProtocol()
|
||||
{
|
||||
var protocolRegistrationTypeList = new List<Type>();
|
||||
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (assembly.Equals(typeof(ProtocolManager).Assembly))
|
||||
{
|
||||
var results = new List<Type>();
|
||||
results.AddRange(assembly.GetTypes());
|
||||
foreach (var type in results)
|
||||
{
|
||||
if (type.IsClass && !type.IsAbstract && typeof(IProtocolRegistration).IsAssignableFrom(type))
|
||||
{
|
||||
protocolRegistrationTypeList.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var protocolRegistrationType in protocolRegistrationTypeList)
|
||||
{
|
||||
var protocolRegistration = (IProtocolRegistration) Activator.CreateInstance(protocolRegistrationType);
|
||||
protocolList[protocolRegistration.ProtocolId()] = protocolRegistration;
|
||||
}
|
||||
{}
|
||||
}
|
||||
|
||||
public static IProtocolRegistration GetProtocol(short protocolId)
|
||||
@@ -44,7 +22,7 @@ namespace CsProtocol
|
||||
var protocol = protocolList[protocolId];
|
||||
if (protocol == null)
|
||||
{
|
||||
throw new Exception("[protocolId:" + protocolId + "]协议不存在");
|
||||
throw new Exception("[protocolId:" + protocolId + "] not exist");
|
||||
}
|
||||
|
||||
return protocol;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CsProtocol.Buffer;
|
||||
|
||||
namespace CsProtocol
|
||||
namespace zfoocs
|
||||
{
|
||||
{}
|
||||
public class {} : IProtocol
|
||||
public class {}
|
||||
{
|
||||
{}
|
||||
|
||||
@@ -15,12 +14,6 @@ namespace CsProtocol
|
||||
{}
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
public short ProtocolId()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user