Auxiliary function: consumes one character from the input. Advances the data pointer to the position immediately preceding the value for the link just traversed (if any); returns flags associated with the link. If no arc with the required label is present, zeroes the data pointer.
| 117 | // returns flags associated with the link. If no arc with the required label is present, |
| 118 | // zeroes the data pointer. |
| 119 | Y_FORCE_INLINE char LeapByte(const char*& datapos, const char* dataend, char label) { |
| 120 | while (datapos < dataend) { |
| 121 | size_t offsetlength, offset; |
| 122 | const char* startpos = datapos; |
| 123 | char flags = *(datapos++); |
| 124 | |
| 125 | if (IsEpsilonLink(flags)) { |
| 126 | // Epsilon link - jump to the specified offset without further checks. |
| 127 | // These links are created during minimization: original uncompressed |
| 128 | // tree does not need them. (If we find a way to package 3 offset lengths |
| 129 | // into 1 byte, we could get rid of them; but it looks like they do no harm. |
| 130 | Y_ASSERT(datapos < dataend); |
| 131 | offsetlength = flags & MT_SIZEMASK; |
| 132 | offset = UnpackOffset(datapos, offsetlength); |
| 133 | if (!offset) |
| 134 | break; |
| 135 | datapos = startpos + offset; |
| 136 | |
| 137 | continue; |
| 138 | } |
| 139 | |
| 140 | char ch = *(datapos++); |
| 141 | |
| 142 | // Left branch |
| 143 | offsetlength = LeftOffsetLen(flags); |
| 144 | if ((unsigned char)label < (unsigned char)ch) { |
| 145 | offset = UnpackOffset(datapos, offsetlength); |
| 146 | if (!offset) |
| 147 | break; |
| 148 | |
| 149 | datapos = startpos + offset; |
| 150 | |
| 151 | continue; |
| 152 | } |
| 153 | |
| 154 | datapos += offsetlength; |
| 155 | |
| 156 | // Right branch |
| 157 | offsetlength = RightOffsetLen(flags); |
| 158 | if ((unsigned char)label > (unsigned char)ch) { |
| 159 | offset = UnpackOffset(datapos, offsetlength); |
| 160 | |
| 161 | if (!offset) |
| 162 | break; |
| 163 | |
| 164 | datapos = startpos + offset; |
| 165 | |
| 166 | continue; |
| 167 | } |
| 168 | |
| 169 | // Got a match; return position right before the contents for the label |
| 170 | datapos += offsetlength; |
| 171 | return flags; |
| 172 | } |
| 173 | |
| 174 | // if we got here, we're past the dataend - bail out ASAP |
| 175 | datapos = nullptr; |
| 176 | return 0; |
no test coverage detected