WireFormat.cs 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc.
  3. // http://code.google.com/p/protobuf/
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. using System.Reflection;
  17. using Google.ProtocolBuffers.Descriptors;
  18. using System.Collections.Generic;
  19. using Google.ProtocolBuffers.Collections;
  20. namespace Google.ProtocolBuffers {
  21. /// <summary>
  22. /// This class is used internally by the Protocol Buffer Library and generated
  23. /// message implementations. It is public only for the sake of those generated
  24. /// messages. Others should not use this class directly.
  25. /// <para>
  26. /// This class contains constants and helper functions useful for dealing with
  27. /// the Protocol Buffer wire format.
  28. /// </para>
  29. /// </summary>
  30. public class WireFormat {
  31. public enum WireType : uint {
  32. Varint = 0,
  33. Fixed64 = 1,
  34. LengthDelimited = 2,
  35. StartGroup = 3,
  36. EndGroup = 4,
  37. Fixed32 = 5
  38. }
  39. internal class MessageSetField {
  40. internal const int Item = 1;
  41. internal const int TypeID = 2;
  42. internal const int Message = 3;
  43. }
  44. internal class MessageSetTag {
  45. internal static readonly uint ItemStart = MakeTag(MessageSetField.Item, WireType.StartGroup);
  46. internal static readonly uint ItemEnd = MakeTag(MessageSetField.Item, WireType.EndGroup);
  47. internal static readonly uint TypeID = MakeTag(MessageSetField.TypeID, WireType.Varint);
  48. internal static readonly uint Message = MakeTag(MessageSetField.Message, WireType.LengthDelimited);
  49. }
  50. private const int TagTypeBits = 3;
  51. private const uint TagTypeMask = (1 << TagTypeBits) - 1;
  52. /// <summary>
  53. /// Given a tag value, determines the wire type (lower 3 bits).
  54. /// </summary>
  55. public static WireType GetTagWireType(uint tag) {
  56. return (WireType) (tag & TagTypeMask);
  57. }
  58. /// <summary>
  59. /// Given a tag value, determines the field number (the upper 29 bits).
  60. /// </summary>
  61. public static int GetTagFieldNumber(uint tag) {
  62. return (int) tag >> TagTypeBits;
  63. }
  64. /// <summary>
  65. /// Makes a tag value given a field number and wire type.
  66. /// TODO(jonskeet): Should we just have a Tag structure?
  67. /// </summary>
  68. public static uint MakeTag(int fieldNumber, WireType wireType) {
  69. return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
  70. }
  71. /// <summary>
  72. /// Immutable mapping from field type to wire type. Built using the attributes on
  73. /// FieldType values.
  74. /// </summary>
  75. public static readonly IDictionary<FieldType, WireType> FieldTypeToWireFormatMap = MapFieldTypes();
  76. private static IDictionary<FieldType, WireType> MapFieldTypes() {
  77. var map = new Dictionary<FieldType, WireType>();
  78. foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) {
  79. FieldType fieldType = (FieldType) field.GetValue(null);
  80. FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
  81. map[fieldType] = mapping.WireType;
  82. }
  83. return Dictionaries.AsReadOnly(map);
  84. }
  85. }
  86. }