1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-27 13:48:49 +08:00
Dušan Borovčanin f10e49e6b5
MF-928 - Change CoAP lib (#1233)
* Switch CoAP lib

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Revert removed adapter code

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* WIP CoAP refactor

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Add auth key

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Fix observers map

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Fix reading message body

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Fix subtopic parsing

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Fix error handling

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Fix multi-protocol communication

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Separate client from observer

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Remove unused config

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Remove TCP option

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Inline error check

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Add logging client errors

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Replace RWMutex since we're not using RLock

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Inline error handling

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

* Inline error handling

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
2020-09-22 11:59:10 +02:00

149 lines
3.7 KiB
Go

// Copyright 2017, Joe Tsai. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.
// Package memfile implements an in-memory emulation of os.File.
package memfile
import (
"errors"
"io"
"sync"
)
var errInvalid = errors.New("invalid argument")
// File is an in-memory emulation of the I/O operations of os.File.
// The zero value for File is an empty file ready to use.
type File struct {
m sync.Mutex
b []byte
i int
}
// New creates and initializes a new File using b as its initial contents.
// The new File takes ownership of b.
func New(b []byte) *File {
return &File{b: b}
}
// Read reads up to len(b) bytes from the File.
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns (0, io.EOF).
func (fb *File) Read(b []byte) (int, error) {
fb.m.Lock()
defer fb.m.Unlock()
n, err := fb.readAt(b, int64(fb.i))
fb.i += n
return n, err
}
// ReadAt reads len(b) bytes from the File starting at byte offset.
// It returns the number of bytes read and the error, if any.
// At end of file, that error is io.EOF.
func (fb *File) ReadAt(b []byte, offset int64) (int, error) {
fb.m.Lock()
defer fb.m.Unlock()
return fb.readAt(b, offset)
}
func (fb *File) readAt(b []byte, off int64) (int, error) {
if off < 0 || int64(int(off)) < off {
return 0, errInvalid
}
if off > int64(len(fb.b)) {
return 0, io.EOF
}
n := copy(b, fb.b[off:])
if n < len(b) {
return n, io.EOF
}
return n, nil
}
// Write writes len(b) bytes to the File.
// It returns the number of bytes written and an error, if any.
// If the current file offset is past the io.EOF, then the space in-between are
// implicitly filled with zero bytes.
func (fb *File) Write(b []byte) (int, error) {
fb.m.Lock()
defer fb.m.Unlock()
n, err := fb.writeAt(b, int64(fb.i))
fb.i += n
return n, err
}
// WriteAt writes len(b) bytes to the File starting at byte offset.
// It returns the number of bytes written and an error, if any.
// If offset lies past io.EOF, then the space in-between are implicitly filled
// with zero bytes.
func (fb *File) WriteAt(b []byte, offset int64) (int, error) {
fb.m.Lock()
defer fb.m.Unlock()
return fb.writeAt(b, offset)
}
func (fb *File) writeAt(b []byte, off int64) (int, error) {
if off < 0 || int64(int(off)) < off {
return 0, errInvalid
}
if off > int64(len(fb.b)) {
fb.truncate(off)
}
n := copy(fb.b[off:], b)
fb.b = append(fb.b, b[n:]...)
return len(b), nil
}
// Seek sets the offset for the next Read or Write on file with offset,
// interpreted according to whence: 0 means relative to the origin of the file,
// 1 means relative to the current offset, and 2 means relative to the end.
func (fb *File) Seek(offset int64, whence int) (int64, error) {
fb.m.Lock()
defer fb.m.Unlock()
var abs int64
switch whence {
case io.SeekStart:
abs = offset
case io.SeekCurrent:
abs = int64(fb.i) + offset
case io.SeekEnd:
abs = int64(len(fb.b)) + offset
default:
return 0, errInvalid
}
if abs < 0 {
return 0, errInvalid
}
fb.i = int(abs)
return abs, nil
}
// Truncate changes the size of the file. It does not change the I/O offset.
func (fb *File) Truncate(n int64) error {
fb.m.Lock()
defer fb.m.Unlock()
return fb.truncate(n)
}
func (fb *File) truncate(n int64) error {
switch {
case n < 0 || int64(int(n)) < n:
return errInvalid
case n <= int64(len(fb.b)):
fb.b = fb.b[:n]
return nil
default:
fb.b = append(fb.b, make([]byte, int(n)-len(fb.b))...)
return nil
}
}
// Bytes returns the full contents of the File.
// The result in only valid until the next Write, WriteAt, or Truncate call.
func (fb *File) Bytes() []byte {
fb.m.Lock()
defer fb.m.Unlock()
return fb.b
}