package activitypub import ( "bytes" "encoding/gob" "fmt" "io" "strings" "unicode/utf8" "github.com/valyala/fastjson" ) // NilLangRef represents a convention for a nil language reference. // It is used for LangRefValue objects without an explicit language key. const NilLangRef LangRef = "-" // DefaultLang represents the default language reference used when using the convenience content generation. var DefaultLang = NilLangRef type ( // LangRef is the type for a language reference code, should be an ISO639-1 language specifier. LangRef string Content []byte // LangRefValue is a type for storing per language values LangRefValue struct { Ref LangRef Value Content } // NaturalLanguageValues is a mapping for multiple language values NaturalLanguageValues []LangRefValue ) func NaturalLanguageValuesNew(values ...LangRefValue) NaturalLanguageValues { n := make(NaturalLanguageValues, len(values)) for i, val := range values { n[i] = val } return n } func DefaultNaturalLanguageValue(content string) NaturalLanguageValues { return NaturalLanguageValuesNew(DefaultLangRef(content)) } func (n NaturalLanguageValues) String() string { cnt := len(n) if cnt == 1 { return n[0].String() } s := strings.Builder{} s.Write([]byte{'['}) for k, v := range n { s.WriteString(v.String()) if k != cnt-1 { s.Write([]byte{','}) } } s.Write([]byte{']'}) return s.String() } func (n NaturalLanguageValues) Get(ref LangRef) Content { for _, val := range n { if val.Ref == ref { return val.Value } } return nil } // Set sets a language, value pair in a NaturalLanguageValues array func (n *NaturalLanguageValues) Set(ref LangRef, v Content) error { found := false for k, vv := range *n { if vv.Ref == ref { (*n)[k] = LangRefValue{ref, v} found = true } } if !found { n.Append(ref, v) } return nil } func (n *NaturalLanguageValues) Add(ref LangRefValue) { *n = append(*n, ref) } var hex = "0123456789abcdef" // safeSet holds the value true if the ASCII character with the given array // position can be represented inside a JSON string without any further // escaping. // // All values are true except for the ASCII control characters (0-31), the // double quote ("), and the backslash character ("\"). var safeSet = [utf8.RuneSelf]bool{ ' ': true, '!': true, '"': false, '#': true, '$': true, '%': true, '&': true, '\'': true, '(': true, ')': true, '*': true, '+': true, ',': true, '-': true, '.': true, '/': true, '0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true, '8': true, '9': true, ':': true, ';': true, '<': true, '=': true, '>': true, '?': true, '@': true, 'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true, 'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true, 'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true, 'Y': true, 'Z': true, '[': true, '\\': false, ']': true, '^': true, '_': true, '`': true, 'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true, 'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true, 'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true, 'y': true, 'z': true, '{': true, '|': true, '}': true, '~': true, '\u007f': true, } // htmlSafeSet holds the value true if the ASCII character with the given // array position can be safely represented inside a JSON string, embedded // inside of HTML