1// Copyright (C) MongoDB, Inc. 2017-present.
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may
4// not use this file except in compliance with the License. You may obtain
5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
7package bsonrw
8
9import (
10	"go.mongodb.org/mongo-driver/bson/bsontype"
11	"go.mongodb.org/mongo-driver/bson/primitive"
12)
13
14// ArrayWriter is the interface used to create a BSON or BSON adjacent array.
15// Callers must ensure they call WriteArrayEnd when they have finished creating
16// the array.
17type ArrayWriter interface {
18	WriteArrayElement() (ValueWriter, error)
19	WriteArrayEnd() error
20}
21
22// DocumentWriter is the interface used to create a BSON or BSON adjacent
23// document. Callers must ensure they call WriteDocumentEnd when they have
24// finished creating the document.
25type DocumentWriter interface {
26	WriteDocumentElement(string) (ValueWriter, error)
27	WriteDocumentEnd() error
28}
29
30// ValueWriter is the interface used to write BSON values. Implementations of
31// this interface handle creating BSON or BSON adjacent representations of the
32// values.
33type ValueWriter interface {
34	WriteArray() (ArrayWriter, error)
35	WriteBinary(b []byte) error
36	WriteBinaryWithSubtype(b []byte, btype byte) error
37	WriteBoolean(bool) error
38	WriteCodeWithScope(code string) (DocumentWriter, error)
39	WriteDBPointer(ns string, oid primitive.ObjectID) error
40	WriteDateTime(dt int64) error
41	WriteDecimal128(primitive.Decimal128) error
42	WriteDouble(float64) error
43	WriteInt32(int32) error
44	WriteInt64(int64) error
45	WriteJavascript(code string) error
46	WriteMaxKey() error
47	WriteMinKey() error
48	WriteNull() error
49	WriteObjectID(primitive.ObjectID) error
50	WriteRegex(pattern, options string) error
51	WriteString(string) error
52	WriteDocument() (DocumentWriter, error)
53	WriteSymbol(symbol string) error
54	WriteTimestamp(t, i uint32) error
55	WriteUndefined() error
56}
57
58// ValueWriterFlusher is a superset of ValueWriter that exposes functionality to flush to the underlying buffer.
59type ValueWriterFlusher interface {
60	ValueWriter
61	Flush() error
62}
63
64// BytesWriter is the interface used to write BSON bytes to a ValueWriter.
65// This interface is meant to be a superset of ValueWriter, so that types that
66// implement ValueWriter may also implement this interface.
67type BytesWriter interface {
68	WriteValueBytes(t bsontype.Type, b []byte) error
69}
70
71// SliceWriter allows a pointer to a slice of bytes to be used as an io.Writer.
72type SliceWriter []byte
73
74func (sw *SliceWriter) Write(p []byte) (int, error) {
75	written := len(p)
76	*sw = append(*sw, p...)
77	return written, nil
78}
79
80type writer []byte
81
82func (w *writer) Write(p []byte) (int, error) {
83	index := len(*w)
84	return w.WriteAt(p, int64(index))
85}
86
87func (w *writer) WriteAt(p []byte, off int64) (int, error) {
88	newend := off + int64(len(p))
89	if newend < int64(len(*w)) {
90		newend = int64(len(*w))
91	}
92
93	if newend > int64(cap(*w)) {
94		buf := make([]byte, int64(2*cap(*w))+newend)
95		copy(buf, *w)
96		*w = buf
97	}
98
99	*w = []byte(*w)[:newend]
100	copy([]byte(*w)[off:], p)
101	return len(p), nil
102}
103