• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "upb/mini_table/message.h"
9 
10 #include <inttypes.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include "upb/mini_table/field.h"
15 
16 // Must be last.
17 #include "upb/port/def.inc"
18 
upb_MiniTable_FindFieldByNumber(const upb_MiniTable * m,uint32_t number)19 const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
20     const upb_MiniTable* m, uint32_t number) {
21   const size_t i = ((size_t)number) - 1;  // 0 wraps to SIZE_MAX
22 
23   // Ideal case: index into dense fields
24   if (i < m->UPB_PRIVATE(dense_below)) {
25     UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number);
26     return &m->UPB_PRIVATE(fields)[i];
27   }
28 
29   // Slow case: binary search
30   int lo = m->UPB_PRIVATE(dense_below);
31   int hi = m->UPB_PRIVATE(field_count) - 1;
32   while (lo <= hi) {
33     int mid = (lo + hi) / 2;
34     uint32_t num = m->UPB_PRIVATE(fields)[mid].UPB_PRIVATE(number);
35     if (num < number) {
36       lo = mid + 1;
37       continue;
38     }
39     if (num > number) {
40       hi = mid - 1;
41       continue;
42     }
43     return &m->UPB_PRIVATE(fields)[mid];
44   }
45   return NULL;
46 }
47 
upb_MiniTable_GetOneof(const upb_MiniTable * m,const upb_MiniTableField * f)48 const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
49                                                  const upb_MiniTableField* f) {
50   if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
51     return NULL;
52   }
53   const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0];
54   const upb_MiniTableField* end =
55       &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
56   for (; ptr < end; ptr++) {
57     if (ptr->presence == (*f).presence) {
58       return ptr;
59     }
60   }
61   return NULL;
62 }
63 
upb_MiniTable_NextOneofField(const upb_MiniTable * m,const upb_MiniTableField ** f)64 bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
65                                   const upb_MiniTableField** f) {
66   const upb_MiniTableField* ptr = *f;
67   const upb_MiniTableField* end =
68       &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
69   while (++ptr < end) {
70     if (ptr->presence == (*f)->presence) {
71       *f = ptr;
72       return true;
73     }
74   }
75   return false;
76 }
77