Skip to content

Commit 3369fe4

Browse files
authored
Merge pull request #4 from gebv/bug-#2
internal refactoring, bug fixes #2
2 parents 3693fef + c4a63dc commit 3369fe4

6 files changed

Lines changed: 628 additions & 216 deletions

File tree

strparam.go renamed to pattern.go

Lines changed: 93 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,73 @@
11
package strparam
22

33
import (
4+
"errors"
45
"fmt"
56
"strings"
67
"unicode/utf8"
78
)
89

10+
// ParseWithName analyzes the pattern, split it into tokens. Saves the schema name.
11+
//
12+
// Iterate over the UTF-8 characters (with correct offset of bytes).
13+
func ParseWithName(name, exp string) (*Pattern, error) {
14+
return parse(name, exp)
15+
}
16+
917
// Parse analyzes the pattern, split it into tokens.
1018
//
1119
// Iterate over the UTF-8 characters (with correct offset of bytes).
12-
func Parse(in string) (*PatternSchema, error) {
20+
func Parse(exp string) (*Pattern, error) {
21+
return parse("", exp)
22+
}
23+
24+
func parse(patternName, exp string) (*Pattern, error) {
25+
if exp == "" {
26+
return nil, errors.New("expression should not is empty")
27+
}
28+
1329
tokens := getlistTokens()
1430
defer putlistTokens(tokens)
1531

1632
// end and start of parameter positions in bytes
1733
var start, end int = 0, 0
18-
// current mode
19-
var mode TokenMode
34+
// current mode (initial as Pattern)
35+
var mode TokenMode = CONST
2036
// is flag of start char of input string
2137
var EOF bool
2238
// number of parameters
2339
var numParams int
2440

25-
// end of input string
41+
// start of input string
2642
tokens = append(tokens, Token{
27-
Mode: BEGINLINE,
43+
Mode: START,
2844
})
2945

3046
// current UTF-8 character in a word
3147
var char rune
3248

3349
// w - character width in bytes
34-
for i, w := 0, 0; i < len(in); i += w {
35-
char, w = utf8.DecodeRuneInString(in[i:])
36-
EOF = i == len(in)-1
50+
for i, w := 0, 0; i < len(exp); i += w {
51+
char, w = utf8.DecodeRuneInString(exp[i:])
52+
EOF = i == len(exp)-1
3753

3854
switch char {
3955
case DefaultStartParam:
4056

4157
// invalid input string if after end border of parameter got new parameter
42-
if i-end == 0 {
58+
if i > 0 && i-end == 0 {
4359
return nil, fmt.Errorf("should be a pattern between the parameters, pos %d", i)
4460
}
4561

46-
tokens = append(tokens, Token{
47-
Mode: PATTERN,
48-
Len: i - end,
49-
Raw: in[end:i],
50-
})
62+
if i-end > 0 {
63+
// skip empty pattern
64+
// - at beginning of the input string the parameter
65+
tokens = append(tokens, Token{
66+
Mode: CONST,
67+
Len: i - end,
68+
Raw: exp[end:i],
69+
})
70+
}
5171

5272
mode = PARAMETER
5373
start = i // sets start position of parameter
@@ -64,10 +84,10 @@ func Parse(in string) (*PatternSchema, error) {
6484

6585
tokens = append(tokens, Token{
6686
Mode: PARAMETER,
67-
Raw: in[start : i+1],
87+
Raw: exp[start : i+1],
6888
})
6989

70-
mode = PATTERN
90+
mode = CONST
7191
end, start = i+1, i+1 // zeroing positions
7292
numParams++
7393
}
@@ -78,36 +98,47 @@ func Parse(in string) (*PatternSchema, error) {
7898
return nil, fmt.Errorf("parameter was not closed, pos %d", i)
7999
}
80100

81-
if mode == PATTERN {
101+
if mode == CONST {
82102
// if exists chars after closed parameter
83103
if i+1-end > 0 {
84104
tokens = append(tokens, Token{
85-
Mode: PATTERN,
105+
Mode: CONST,
86106
Len: i + 1 - end,
87-
Raw: in[end : i+1],
107+
Raw: exp[end : i+1],
88108
})
89109
}
90110
}
91111
}
92112
}
93113

94-
// start of input string
114+
// end of input string
95115
tokens = append(tokens, Token{
96-
Mode: ENDLINE,
116+
Mode: END,
117+
Raw: patternName,
97118
})
98119

99-
return &PatternSchema{
100-
Pattern: in,
120+
return &Pattern{
101121
Tokens: tokens,
102122
NumParams: numParams,
103123
}, nil
104124
}
105125

106126
// Lookup returns list params if input string matched to schema.
107-
func (s *PatternSchema) Lookup(in string) (bool, Params) {
127+
//
128+
// NOTE: nothing (empty list of tokens) not matches to anything.
129+
func (s *Pattern) Lookup(in string) (bool, Params) {
130+
if s == nil {
131+
return false, nil
132+
}
133+
108134
params := getListParams()
109135
defer putListParams(params)
110136

137+
if len(s.Tokens) == 0 {
138+
// nothing not matches to anything
139+
return false, nil
140+
}
141+
111142
// this is the sum of the lengths of the patterns and found value of parameters
112143
var offset int
113144

@@ -117,12 +148,9 @@ func (s *PatternSchema) Lookup(in string) (bool, Params) {
117148
}
118149

119150
switch t.Mode {
120-
case BEGINLINE:
121-
case ENDLINE:
122-
if offset < len(in) {
123-
// have tail without pattern
124-
return false, nil
125-
}
151+
case START:
152+
case END:
153+
goto exitloop
126154
case PARAMETER_PARSED:
127155
params = append(params, Param{
128156
Name: t.ParamName(),
@@ -132,13 +160,13 @@ func (s *PatternSchema) Lookup(in string) (bool, Params) {
132160
case PARAMETER:
133161
_next := s.Tokens[num+1]
134162
switch _next.Mode {
135-
case ENDLINE:
163+
case END:
136164
params = append(params, Param{
137165
Name: t.ParamName(),
138166
Value: in[offset:],
139167
})
140168
offset += len(in) - offset
141-
case PATTERN:
169+
case CONST:
142170
if found := strings.Index(in[offset:], _next.Raw); found > -1 {
143171
params = append(params, Param{
144172
Name: t.ParamName(),
@@ -152,28 +180,57 @@ func (s *PatternSchema) Lookup(in string) (bool, Params) {
152180
default:
153181
return false, nil
154182
}
155-
case PATTERN:
183+
case CONST:
156184
if in[offset:offset+t.Len] == t.Raw {
157185
// add the length of the pattern
158186
offset += t.Len
159187
} else {
188+
// forced return because pattern is not matched
160189
return false, nil
161190
}
162191
}
163192
}
164193

194+
exitloop:
195+
196+
// offset did not seeking to end of by input value
197+
if len(in) != offset {
198+
return false, nil
199+
}
200+
201+
// received an unexpected number of parameters
165202
if len(params) != s.NumParams {
166203
return false, nil
167204
}
205+
168206
return true, params
169207
}
170208

171-
type PatternSchema struct {
172-
Pattern string
173-
Tokens []Token
209+
type Pattern struct {
210+
Tokens Tokens
174211
NumParams int
175212
}
176213

214+
// String returns schema of pattern.
215+
func (s Pattern) String() string {
216+
return s.Tokens.String()
217+
}
218+
219+
// Name returns name of pattern (by end token if sets).
220+
func (s Pattern) Name() string {
221+
if s.Tokens == nil {
222+
return ""
223+
}
224+
if len(s.Tokens) <= 1 {
225+
return ""
226+
}
227+
endToken := s.Tokens[len(s.Tokens)-1]
228+
if endToken.Mode != END {
229+
return ""
230+
}
231+
return endToken.Raw
232+
}
233+
177234
type Param struct {
178235
Name string
179236
Value string

0 commit comments

Comments
 (0)