blob: 0ea933225672e6cd177497c0b09c33de271e6b26 [file] [log] [blame]
Jon Skeet68036862008-10-22 13:30:34 +01001// 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.
16using System;
17using System.Reflection;
18using Google.ProtocolBuffers.Descriptors;
19using System.Collections.Generic;
20using Google.ProtocolBuffers.Collections;
21namespace Google.ProtocolBuffers {
22
23 /// <summary>
24 /// This class is used internally by the Protocol Buffer Library and generated
25 /// message implementations. It is public only for the sake of those generated
26 /// messages. Others should not use this class directly.
27 /// <para>
28 /// This class contains constants and helper functions useful for dealing with
29 /// the Protocol Buffer wire format.
30 /// </para>
31 /// </summary>
32 public static class WireFormat {
33 public enum WireType : uint {
34 Varint = 0,
35 Fixed64 = 1,
36 LengthDelimited = 2,
37 StartGroup = 3,
38 EndGroup = 4,
39 Fixed32 = 5
40 }
41
42 internal static class MessageSetField {
43 internal const int Item = 1;
44 internal const int TypeID = 2;
45 internal const int Message = 3;
46 }
47
48 internal static class MessageSetTag {
49 internal static readonly uint ItemStart = MakeTag(MessageSetField.Item, WireType.StartGroup);
50 internal static readonly uint ItemEnd = MakeTag(MessageSetField.Item, WireType.EndGroup);
51 internal static readonly uint TypeID = MakeTag(MessageSetField.TypeID, WireType.Varint);
52 internal static readonly uint Message = MakeTag(MessageSetField.Message, WireType.LengthDelimited);
53 }
54
55 private const int TagTypeBits = 3;
56 private const uint TagTypeMask = (1 << TagTypeBits) - 1;
57
58 /// <summary>
59 /// Given a tag value, determines the wire type (lower 3 bits).
60 /// </summary>
61 public static WireType GetTagWireType(uint tag) {
62 return (WireType) (tag & TagTypeMask);
63 }
64
65 /// <summary>
66 /// Given a tag value, determines the field number (the upper 29 bits).
67 /// </summary>
68 public static int GetTagFieldNumber(uint tag) {
69 return (int) tag >> TagTypeBits;
70 }
71
72 /// <summary>
73 /// Makes a tag value given a field number and wire type.
74 /// TODO(jonskeet): Should we just have a Tag structure?
75 /// </summary>
76 public static uint MakeTag(int fieldNumber, WireType wireType) {
77 return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
78 }
79
80 /// <summary>
81 /// Converts a field type to its wire type. Done with a switch for the sake
82 /// of speed - this is significantly faster than a dictionary lookup.
83 /// </summary>
84 public static WireType GetWireType(FieldType fieldType) {
85 switch (fieldType) {
86 case FieldType.Double:
87 return WireType.Fixed64;
88 case FieldType.Float:
89 return WireType.Fixed32;
90 case FieldType.Int64:
91 case FieldType.UInt64:
92 case FieldType.Int32:
93 return WireType.Varint;
94 case FieldType.Fixed64:
95 return WireType.Fixed64;
96 case FieldType.Fixed32:
97 return WireType.Fixed32;
98 case FieldType.Bool:
99 return WireType.Varint;
100 case FieldType.String:
101 return WireType.LengthDelimited;
102 case FieldType.Group:
103 return WireType.StartGroup;
104 case FieldType.Message:
105 case FieldType.Bytes:
106 return WireType.LengthDelimited;
107 case FieldType.UInt32:
108 return WireType.Varint;
109 case FieldType.SFixed32:
110 return WireType.Fixed32;
111 case FieldType.SFixed64:
112 return WireType.Fixed64;
113 case FieldType.SInt32:
114 case FieldType.SInt64:
115 case FieldType.Enum:
116 return WireType.Varint;
117 default:
118 throw new ArgumentOutOfRangeException("No such field type");
119 }
120 }
121 }
122}