From c5224da4a2f250b9d1ca6cff32a88248423a0709 Mon Sep 17 00:00:00 2001 From: Patricio Whittingslow Date: Wed, 29 Jul 2026 17:01:40 -0300 Subject: [PATCH] unexport kvBuffer --- http/httpraw/cookie.go | 4 +- http/httpraw/form.go | 4 +- http/httpraw/kvbuffer.go | 102 +++++++++++++++++++-------------------- http/httpraw/parse.go | 2 +- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/http/httpraw/cookie.go b/http/httpraw/cookie.go index 0606c00..00c3717 100644 --- a/http/httpraw/cookie.go +++ b/http/httpraw/cookie.go @@ -7,11 +7,11 @@ import ( // Cookie implements cookie key-value parsing. Methods function similarly to eponymous [Header] methods. // Cookie represents a single-line Cookie header value in a HTTP header, much like the standard library Cookie. type Cookie struct { - kv KVBuffer + kv kvBuffer } // EnableBufferGrowth allows the cookie's buffer to grow past what [Cookie.Reset] was -// handed. See [KVBuffer.EnableBufferGrowth]. +// handed. See [kvBuffer.EnableBufferGrowth]. func (c *Cookie) EnableBufferGrowth(enableBufferGrowth bool) { c.kv.EnableBufferGrowth(enableBufferGrowth) } diff --git a/http/httpraw/form.go b/http/httpraw/form.go index 5ba7c43..848cbef 100644 --- a/http/httpraw/form.go +++ b/http/httpraw/form.go @@ -8,11 +8,11 @@ package httpraw // undecoded, until [Form.Decode] rewrites them in place. The caller bounds the // data: Form parses the buffer it is handed and reads nothing more. type Form struct { - kv KVBuffer + kv kvBuffer } // EnableBufferGrowth allows the form's buffer to grow past what [Form.Reset] was -// handed. See [KVBuffer.EnableBufferGrowth]. +// handed. See [kvBuffer.EnableBufferGrowth]. func (f *Form) EnableBufferGrowth(enableGrowth bool) { f.kv.EnableBufferGrowth(enableGrowth) } // Reset discards parsed pairs and sets the buffer to parse in place. diff --git a/http/httpraw/kvbuffer.go b/http/httpraw/kvbuffer.go index 0a35ea4..17c0149 100644 --- a/http/httpraw/kvbuffer.go +++ b/http/httpraw/kvbuffer.go @@ -8,23 +8,23 @@ import ( "github.com/soypat/lneto/internal" ) -// KVBuffer is a common key-value store engine for Cookie, Form, Header and other HTTP abstractions that need +// kvBuffer is a common key-value store engine for Cookie, Form, Header and other HTTP abstractions that need // a key-value store with underlying buffer memory. -type KVBuffer struct { +type kvBuffer struct { buf []byte kvs []argsKV flags Flags } -func (mb *KVBuffer) free() int { return cap(mb.buf) - len(mb.buf) } +func (mb *kvBuffer) free() int { return cap(mb.buf) - len(mb.buf) } // BufferRaw returns the underlying buffer, its length being the portion in use. // Stored pairs alias it, so writing to it mangles them. -func (mb *KVBuffer) BufferRaw() []byte { return mb.buf } +func (mb *kvBuffer) BufferRaw() []byte { return mb.buf } -// EnableBufferGrowth allows the buffer to grow past the memory [KVBuffer.Reset] +// EnableBufferGrowth allows the buffer to grow past the memory [kvBuffer.Reset] // was handed. The setting outlives Reset; with growth off callers get [ErrBufferExhausted]. -func (mb *KVBuffer) EnableBufferGrowth(enableGrowth bool) { +func (mb *kvBuffer) EnableBufferGrowth(enableGrowth bool) { if enableGrowth { mb.flags &^= flagNoBufferGrow } else { @@ -32,14 +32,14 @@ func (mb *KVBuffer) EnableBufferGrowth(enableGrowth bool) { } } -func (mb *KVBuffer) discardKVs() { mb.kvs = mb.kvs[:0] } +func (mb *kvBuffer) discardKVs() { mb.kvs = mb.kvs[:0] } -// BufferGrowthEnabled reports whether the buffer may grow, see [KVBuffer.EnableBufferGrowth]. -func (mb *KVBuffer) BufferGrowthEnabled() bool { return !mb.flags.HasAny(flagNoBufferGrow) } +// BufferGrowthEnabled reports whether the buffer may grow, see [kvBuffer.EnableBufferGrowth]. +func (mb *kvBuffer) BufferGrowthEnabled() bool { return !mb.flags.HasAny(flagNoBufferGrow) } // ReadFromBytes appends buf to the underlying buffer, accumulating data to parse. // Returns [ErrBufferExhausted] when buf does not fit and growth is disabled. -func (mb *KVBuffer) ReadFromBytes(buf []byte) error { +func (mb *kvBuffer) ReadFromBytes(buf []byte) error { if len(buf) == 0 { return io.ErrNoProgress // Nothing handed over, not a buffer problem. } else if mb.flags.HasAny(flagMangledBuffer) { @@ -57,7 +57,7 @@ func (mb *KVBuffer) ReadFromBytes(buf []byte) error { // ReadLimited appends at most limit bytes read from r to the underlying buffer. // A read returning data alongside [io.EOF] reports a nil error, later ones io.EOF. -func (mb *KVBuffer) ReadLimited(r io.Reader, limit int) (int, error) { +func (mb *kvBuffer) ReadLimited(r io.Reader, limit int) (int, error) { free := mb.free() growthEnabled := mb.BufferGrowthEnabled() if !growthEnabled && (free == 0 || free < limit) || len(mb.buf) >= maxBufLen { @@ -83,7 +83,7 @@ func (mb *KVBuffer) ReadLimited(r io.Reader, limit int) (int, error) { // Reset discards all pairs and takes buf as the buffer to parse in place, nil // reusing the current one. kvCap sizes the pair table. Only the growth setting survives. -func (mb *KVBuffer) Reset(buf []byte, kvCap int) { +func (mb *kvBuffer) Reset(buf []byte, kvCap int) { if buf == nil { mb.buf = mb.buf[:0] } else { @@ -95,7 +95,7 @@ func (mb *KVBuffer) Reset(buf []byte, kvCap int) { // CopyFrom replaces the receiver's contents with a copy of src, sharing no // memory with it afterwards. -func (mb *KVBuffer) CopyFrom(src *KVBuffer) { +func (mb *kvBuffer) CopyFrom(src *kvBuffer) { mb.buf = append(mb.buf[:0], src.buf...) mb.kvs = append(mb.kvs[:0], src.kvs...) } @@ -103,8 +103,8 @@ func (mb *KVBuffer) CopyFrom(src *KVBuffer) { // Get returns the value of the first pair matching key. // Bytes are compared as stored, so if using a Form call [Form.Decode] first when keys may be encoded. // Returns nil for an absent key and for a valueless pair alike, so use -// [KVBuffer.Present] to tell the two apart. -func (mb *KVBuffer) Get(key string) []byte { +// [kvBuffer.Present] to tell the two apart. +func (mb *kvBuffer) Get(key string) []byte { i := mb.getIdx(key) if i < 0 { return nil @@ -113,7 +113,7 @@ func (mb *KVBuffer) Get(key string) []byte { } // ForEach iterates over the cookie's key-value pairs as stored until cb returns false. -func (c *KVBuffer) ForEach(cb func(key, value []byte) bool) { +func (c *kvBuffer) ForEach(cb func(key, value []byte) bool) { nc := len(c.kvs) for i := range nc { if !c.kvs[i].isValid() { @@ -125,12 +125,12 @@ func (c *KVBuffer) ForEach(cb func(key, value []byte) bool) { } // Has returns true if key is present, with or without a value. -func (mb *KVBuffer) Present(key string) bool { // TODO: rename to Has. +func (mb *kvBuffer) Present(key string) bool { // TODO: rename to Has. return mb.getIdx(key) >= 0 } // Has returns true if key is present, with or without a value. -func (mb *KVBuffer) HasKeyValue(key, value string) bool { +func (mb *kvBuffer) HasKeyValue(key, value string) bool { idx := mb.getIdx(key) if idx >= 0 { return b2s(mb.musttoken(mb.kvs[idx].value)) == value @@ -138,22 +138,22 @@ func (mb *KVBuffer) HasKeyValue(key, value string) bool { return false } -// Add appends a pair, keeping any already sharing the key: use [KVBuffer.Set] +// Add appends a pair, keeping any already sharing the key: use [kvBuffer.Set] // to replace instead. Reports false if the buffer could not hold it. -func (mb *KVBuffer) Add(key, value string) (enoughSpace bool) { +func (mb *kvBuffer) Add(key, value string) (enoughSpace bool) { mb.appendPair(key, value) return mb.getIdx(key) >= 0 } // Set replaces key's value and invalidates every other pair sharing the key, so -// a following [KVBuffer.Get] sees exactly one value. +// a following [kvBuffer.Get] sees exactly one value. // // It rewrites in place when it can: of the pairs it would invalidate it keeps // the smallest whose key and value regions both still hold the new pair, // leaving the roomier regions for a later Set. When none fits the pair is -// appended with [KVBuffer.Add] and the invalidated regions are stranded, since +// appended with [kvBuffer.Add] and the invalidated regions are stranded, since // nothing here compacts the buffer. -func (mb *KVBuffer) Set(key, value string) (enoughSpace bool) { +func (mb *kvBuffer) Set(key, value string) (enoughSpace bool) { reuse := mb.takeReusableSlot(key, len(key), len(value)) if reuse < 0 { return mb.Add(key, value) @@ -162,9 +162,9 @@ func (mb *KVBuffer) Set(key, value string) (enoughSpace bool) { return true } -// SetInt is [KVBuffer.Set]'s integer counterpart. It formats value straight into +// SetInt is [kvBuffer.Set]'s integer counterpart. It formats value straight into // the slot it reuses, so overwriting a pair never allocates. -func (mb *KVBuffer) SetInt(key string, value int64, base int) (enoughSpace bool) { +func (mb *kvBuffer) SetInt(key string, value int64, base int) (enoughSpace bool) { reuse := mb.takeReusableSlot(key, len(key), internal.IntLen(value, base)) if reuse < 0 { return mb.appendPairInt(key, value, base) @@ -184,7 +184,7 @@ func (mb *KVBuffer) SetInt(key string, value int64, base int) (enoughSpace bool) // whose key and value regions hold keyLen and valueLen bytes, whose index it // returns. It returns -1 when no surviving slot fits, meaning the caller must // append instead. -func (mb *KVBuffer) takeReusableSlot(key string, keyLen, valueLen int) int { +func (mb *kvBuffer) takeReusableSlot(key string, keyLen, valueLen int) int { reuse := -1 for i := range mb.kvs { kv := &mb.kvs[i] @@ -210,7 +210,7 @@ func (mb *KVBuffer) takeReusableSlot(key string, keyLen, valueLen int) int { // overwriteAt writes key and value over the regions pair i already owns. The // caller must have checked both fit; the bytes freed by a shorter pair are // stranded, not reclaimed. -func (mb *KVBuffer) overwriteAt(i int, key, value string) { +func (mb *kvBuffer) overwriteAt(i int, key, value string) { mb.flags |= flagMangledBuffer kv := &mb.kvs[i] copy(mb.buf[kv.key.start:], key) @@ -219,7 +219,7 @@ func (mb *KVBuffer) overwriteAt(i int, key, value string) { kv.value.len = tokint(len(value)) } -func (mb *KVBuffer) setInternal(key, value []byte) (enoughSpace bool) { +func (mb *kvBuffer) setInternal(key, value []byte) (enoughSpace bool) { if !mb.canAddOneKV() { return false } @@ -231,19 +231,19 @@ func (mb *KVBuffer) setInternal(key, value []byte) (enoughSpace bool) { return true } -// Len returns the number of slots stored, counting those [KVBuffer.Set] invalidated. -func (mb *KVBuffer) Len() int { return len(mb.kvs) } +// Len returns the number of slots stored, counting those [kvBuffer.Set] invalidated. +func (mb *kvBuffer) Len() int { return len(mb.kvs) } // At returns the i'th pair in wire order. value is nil for a pair holding none, // which is what tells a form's "ok" from "ok=". -func (mb *KVBuffer) At(i int) (key, value []byte) { +func (mb *kvBuffer) At(i int) (key, value []byte) { kv := mb.kvs[i] if !kv.HasValue() { return mb.musttoken(kv.key), nil } return mb.musttoken(kv.key), mb.musttoken(kv.value) } -func (mb *KVBuffer) setAt(i int, k, v []byte) { +func (mb *kvBuffer) setAt(i int, k, v []byte) { mb.flags |= flagMangledBuffer // Route through slice, not bytes2tok: a nil v is a pair with no '=' and must // stay absent rather than trip the alias check on a nil pointer. @@ -253,18 +253,18 @@ func (mb *KVBuffer) setAt(i int, k, v []byte) { } } -// AtKey is [KVBuffer.At] limited to the i'th key. -func (mb *KVBuffer) AtKey(i int) (key []byte) { return mb.musttoken(mb.kvs[i].key) } +// AtKey is [kvBuffer.At] limited to the i'th key. +func (mb *kvBuffer) AtKey(i int) (key []byte) { return mb.musttoken(mb.kvs[i].key) } -// AtValue is [KVBuffer.At] limited to the i'th value, nil when the pair holds none. -func (mb *KVBuffer) AtValue(i int) (key []byte) { +// AtValue is [kvBuffer.At] limited to the i'th value, nil when the pair holds none. +func (mb *kvBuffer) AtValue(i int) (key []byte) { if !mb.kvs[i].HasValue() { return nil } return mb.musttoken(mb.kvs[i].value) } -func (mb *KVBuffer) getIdx(key string) int { +func (mb *kvBuffer) getIdx(key string) int { for i, kv := range mb.kvs { if kv.isValid() && b2s(mb.musttoken(kv.key)) == key { return i @@ -278,7 +278,7 @@ func (mb *KVBuffer) getIdx(key string) int { // mustAppendSlice). It returns false and sets flagOOMReached when the space // cannot be guaranteed: a tokint offset overflow, or a full buffer with // flagNoBufferGrow set. -func (mb *KVBuffer) reserve(need int) (enoughSpace bool) { +func (mb *kvBuffer) reserve(need int) (enoughSpace bool) { if len(mb.buf) == 0 { need++ // mustAppend* reserves byte 0 on an empty buffer. } @@ -296,7 +296,7 @@ func (mb *KVBuffer) reserve(need int) (enoughSpace bool) { return true } -func (mb *KVBuffer) appendPair(key, value string) bool { +func (mb *kvBuffer) appendPair(key, value string) bool { if !mb.canAddOneKV() || !mb.reserve(len(key)+len(value)) { return false } @@ -308,7 +308,7 @@ func (mb *KVBuffer) appendPair(key, value string) bool { return true } -func (mb *KVBuffer) appendPairInt(key string, value int64, base int) bool { +func (mb *kvBuffer) appendPairInt(key string, value int64, base int) bool { vlen := internal.IntLen(value, base) if !mb.canAddOneKV() || !mb.reserve(len(key)+vlen) { return false @@ -321,11 +321,11 @@ func (mb *KVBuffer) appendPairInt(key string, value int64, base int) bool { return true } -func (mb *KVBuffer) canAddOneKV() (enoughSpace bool) { +func (mb *kvBuffer) canAddOneKV() (enoughSpace bool) { return len(mb.kvs) < cap(mb.kvs) || mb.flags&flagNoBufferGrow == 0 } -func (mb *KVBuffer) mustAppendSlice(value string) headerSlice { +func (mb *kvBuffer) mustAppendSlice(value string) headerSlice { L := len(mb.buf) if L == 0 { L++ // Valid key-values start after 0. @@ -335,7 +335,7 @@ func (mb *KVBuffer) mustAppendSlice(value string) headerSlice { return mb.slice(mb.buf[L : L+len(value)]) } -func (hb *KVBuffer) mustAppendInt(value int64, base int) headerSlice { +func (hb *kvBuffer) mustAppendInt(value int64, base int) headerSlice { L := len(hb.buf) if L == 0 { L++ // Valid key-values start after byte 0. @@ -347,7 +347,7 @@ func (hb *KVBuffer) mustAppendInt(value int64, base int) headerSlice { // reuseOrAppend writes value over tok's slot when it fits there, avoiding any // buffer growth; otherwise it appends a fresh slot. -func (mb *KVBuffer) reuseOrAppend(tok headerSlice, value string) headerSlice { +func (mb *kvBuffer) reuseOrAppend(tok headerSlice, value string) headerSlice { if tok.len > tokint(len(value)) { copy(mb.musttoken(tok), value) tok.len = tokint(len(value)) @@ -358,7 +358,7 @@ func (mb *KVBuffer) reuseOrAppend(tok headerSlice, value string) headerSlice { // appendSlice reserves space (growing or flagging OOM) and appends value as a // new slot. -func (mb *KVBuffer) appendSlice(value string) headerSlice { +func (mb *kvBuffer) appendSlice(value string) headerSlice { debuglog("http:appendslice:start") if !mb.reserve(len(value)) { return headerSlice{} // Drop and flag OOM; never panic. @@ -367,8 +367,8 @@ func (mb *KVBuffer) appendSlice(value string) headerSlice { return mb.mustAppendSlice(value) } -// reuseOrAppendInt is [KVBuffer.reuseOrAppend]'s integer counterpart. -func (mb *KVBuffer) reuseOrAppendInt(tok headerSlice, value int64, base int) headerSlice { +// reuseOrAppendInt is [kvBuffer.reuseOrAppend]'s integer counterpart. +func (mb *kvBuffer) reuseOrAppendInt(tok headerSlice, value int64, base int) headerSlice { n := internal.IntLen(value, base) if int(tok.len) >= n { // Reuse: format directly over the existing slot. No free space needed @@ -382,7 +382,7 @@ func (mb *KVBuffer) reuseOrAppendInt(tok headerSlice, value int64, base int) hea } // appendInt reserves space (growing or flagging OOM) and appends value as a new slot. -func (mb *KVBuffer) appendInt(value int64, base, n int) headerSlice { +func (mb *kvBuffer) appendInt(value int64, base, n int) headerSlice { if !mb.reserve(n) { return headerSlice{} // Drop and flag OOM; never panic. } @@ -390,17 +390,17 @@ func (mb *KVBuffer) appendInt(value int64, base, n int) headerSlice { return mb.mustAppendInt(value, base) } -func (mb *KVBuffer) slice(value []byte) headerSlice { +func (mb *kvBuffer) slice(value []byte) headerSlice { if value == nil { return headerSlice{} } return bytes2tok(mb.buf, value) } -func (mb KVBuffer) musttoken(slice headerSlice) []byte { +func (mb kvBuffer) musttoken(slice headerSlice) []byte { return tok2bytes(mb.buf, slice) } -func (mb *KVBuffer) noKV() argsKV { return argsKV{} } +func (mb *kvBuffer) noKV() argsKV { return argsKV{} } type tokint = uint16 diff --git a/http/httpraw/parse.go b/http/httpraw/parse.go index 07d9e0a..7460da1 100644 --- a/http/httpraw/parse.go +++ b/http/httpraw/parse.go @@ -50,7 +50,7 @@ var ( const maxBufLen = 0xffff type headerBuf struct { - kv KVBuffer + kv kvBuffer // buf[:len] holds entire HTTP header data, which may be normalized by [flags]. buf[off:len] holds data not yet processed during parsing. // buf []byte // offset into buf for parsing.