github.com/iDigitalFlame/xmt@v0.5.4/data/chunk_reader.go (about)

     1  // Copyright (C) 2020 - 2023 iDigitalFlame
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU General Public License as published by
     5  // the Free Software Foundation, either version 3 of the License, or
     6  // any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU General Public License
    14  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    15  //
    16  
    17  package data
    18  
    19  import "io"
    20  
    21  // Int reads the value from the Chunk payload buffer.
    22  func (c *Chunk) Int() (int, error) {
    23  	v, err := c.Uint64()
    24  	if err != nil {
    25  		return 0, err
    26  	}
    27  	return int(v), nil
    28  }
    29  
    30  // Uint reads the value from the Chunk payload buffer.
    31  func (c *Chunk) Uint() (uint, error) {
    32  	v, err := c.Uint64()
    33  	if err != nil {
    34  		return 0, err
    35  	}
    36  	return uint(v), nil
    37  }
    38  
    39  // Bool reads the value from the Chunk payload buffer.
    40  func (c *Chunk) Bool() (bool, error) {
    41  	v, err := c.Uint8()
    42  	if err != nil {
    43  		return false, err
    44  	}
    45  	return v == 1, nil
    46  }
    47  
    48  // Int8 reads the value from the Chunk payload buffer.
    49  func (c *Chunk) Int8() (int8, error) {
    50  	v, err := c.Uint8()
    51  	if err != nil {
    52  		return 0, err
    53  	}
    54  	return int8(v), nil
    55  }
    56  
    57  // ReadInt reads the value from the Chunk payload buffer into the provided pointer.
    58  func (c *Chunk) ReadInt(p *int) error {
    59  	v, err := c.Int()
    60  	if err != nil {
    61  		return err
    62  	}
    63  	*p = v
    64  	return nil
    65  }
    66  
    67  // Int16 reads the value from the Chunk payload buffer.
    68  func (c *Chunk) Int16() (int16, error) {
    69  	v, err := c.Uint16()
    70  	if err != nil {
    71  		return 0, err
    72  	}
    73  	return int16(v), nil
    74  }
    75  
    76  // Int32 reads the value from the Chunk payload buffer.
    77  func (c *Chunk) Int32() (int32, error) {
    78  	v, err := c.Uint32()
    79  	if err != nil {
    80  		return 0, err
    81  	}
    82  	return int32(v), nil
    83  }
    84  
    85  // Int64 reads the value from the Chunk payload buffer.
    86  func (c *Chunk) Int64() (int64, error) {
    87  	v, err := c.Uint64()
    88  	if err != nil {
    89  		return 0, err
    90  	}
    91  	return int64(v), nil
    92  }
    93  
    94  // Uint8 reads the value from the Chunk payload buffer.
    95  func (c *Chunk) Uint8() (uint8, error) {
    96  	if c.checkBounds(1) {
    97  		return 0, io.EOF
    98  	}
    99  	v := c.buf[c.rpos]
   100  	c.rpos++
   101  	return v, nil
   102  }
   103  
   104  // Bytes reads the value from the Chunk payload buffer.
   105  func (c *Chunk) Bytes() ([]byte, error) {
   106  	t, err := c.Uint8()
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	var l uint64
   111  	switch t {
   112  	case 0:
   113  		return nil, nil
   114  	case 1, 2:
   115  		n, err2 := c.Uint8()
   116  		if err2 != nil {
   117  			return nil, err2
   118  		}
   119  		l = uint64(n)
   120  	case 3, 4:
   121  		n, err2 := c.Uint16()
   122  		if err2 != nil {
   123  			return nil, err2
   124  		}
   125  		l = uint64(n)
   126  	case 5, 6:
   127  		n, err2 := c.Uint32()
   128  		if err2 != nil {
   129  			return nil, err2
   130  		}
   131  		l = uint64(n)
   132  	case 7, 8:
   133  		n, err2 := c.Uint64()
   134  		if err2 != nil {
   135  			return nil, err2
   136  		}
   137  		l = n
   138  	default:
   139  		return nil, ErrInvalidType
   140  	}
   141  	if l == 0 {
   142  		// NOTE(dij): Technically we should return (nil, nil)
   143  		//            But! Our spec states that 0 size should be ID:0
   144  		//            NOT ID:0,SIZE:0. So something made a fucky wucky here.
   145  		return nil, io.ErrUnexpectedEOF
   146  	}
   147  	if l > MaxSlice {
   148  		return nil, ErrTooLarge
   149  	}
   150  	// NOTE(dij): This looks like an awesome optimization, we reslice instead of
   151  	//            allocating and writing a new slice.
   152  	if n := c.Size(); n < c.rpos+int(l) {
   153  		o := c.buf[c.rpos:]
   154  		c.rpos = n
   155  		return o, io.EOF
   156  	}
   157  	o := c.buf[c.rpos : uint64(c.rpos)+l]
   158  	c.rpos += int(l)
   159  	return o, nil
   160  }
   161  
   162  // ReadUint reads the value from the Chunk payload buffer into the provided pointer.
   163  func (c *Chunk) ReadUint(p *uint) error {
   164  	v, err := c.Uint()
   165  	if err != nil {
   166  		return err
   167  	}
   168  	*p = v
   169  	return nil
   170  }
   171  
   172  // ReadInt8 reads the value from the Chunk payload buffer into the provided pointer.
   173  func (c *Chunk) ReadInt8(p *int8) error {
   174  	v, err := c.Int8()
   175  	if err != nil {
   176  		return err
   177  	}
   178  	*p = v
   179  	return nil
   180  }
   181  
   182  // ReadBool reads the value from the Chunk payload buffer into the provided pointer.
   183  func (c *Chunk) ReadBool(p *bool) error {
   184  	v, err := c.Bool()
   185  	if err != nil {
   186  		return err
   187  	}
   188  	*p = v
   189  	return nil
   190  }
   191  
   192  // Uint16 reads the value from the Chunk payload buffer.
   193  func (c *Chunk) Uint16() (uint16, error) {
   194  	if c.checkBounds(2) {
   195  		return 0, io.EOF
   196  	}
   197  	_ = c.buf[c.rpos+1]
   198  	v := uint16(c.buf[c.rpos+1]) | uint16(c.buf[c.rpos])<<8
   199  	c.rpos += 2
   200  	return v, nil
   201  }
   202  
   203  // Uint32 reads the value from the Chunk payload buffer.
   204  func (c *Chunk) Uint32() (uint32, error) {
   205  	if c.checkBounds(4) {
   206  		return 0, io.EOF
   207  	}
   208  	_ = c.buf[c.rpos+3]
   209  	v := uint32(c.buf[c.rpos+3]) | uint32(c.buf[c.rpos+2])<<8 | uint32(c.buf[c.rpos+1])<<16 | uint32(c.buf[c.rpos])<<24
   210  	c.rpos += 4
   211  	return v, nil
   212  }
   213  
   214  // Uint64 reads the value from the Chunk payload buffer.
   215  func (c *Chunk) Uint64() (uint64, error) {
   216  	if c.checkBounds(8) {
   217  		return 0, io.EOF
   218  	}
   219  	_ = c.buf[c.rpos+7]
   220  	v := uint64(c.buf[c.rpos+7]) | uint64(c.buf[c.rpos+6])<<8 | uint64(c.buf[c.rpos+5])<<16 | uint64(c.buf[c.rpos+4])<<24 |
   221  		uint64(c.buf[c.rpos+3])<<32 | uint64(c.buf[c.rpos+2])<<40 | uint64(c.buf[c.rpos+1])<<48 | uint64(c.buf[c.rpos])<<56
   222  	c.rpos += 8
   223  	return v, nil
   224  }
   225  
   226  // ReadInt16 reads the value from the Chunk payload buffer into the provided pointer.
   227  func (c *Chunk) ReadInt16(p *int16) error {
   228  	v, err := c.Int16()
   229  	if err != nil {
   230  		return err
   231  	}
   232  	*p = v
   233  	return nil
   234  }
   235  
   236  // ReadInt32 reads the value from the Chunk payload buffer into the provided pointer.
   237  func (c *Chunk) ReadInt32(p *int32) error {
   238  	v, err := c.Int32()
   239  	if err != nil {
   240  		return err
   241  	}
   242  	*p = v
   243  	return nil
   244  }
   245  
   246  // ReadInt64 reads the value from the Chunk payload buffer into the provided pointer.
   247  func (c *Chunk) ReadInt64(p *int64) error {
   248  	v, err := c.Int64()
   249  	if err != nil {
   250  		return err
   251  	}
   252  	*p = v
   253  	return nil
   254  }
   255  
   256  // ReadUint8 reads the value from the Chunk payload buffer into the provided pointer.
   257  func (c *Chunk) ReadUint8(p *uint8) error {
   258  	v, err := c.Uint8()
   259  	if err != nil {
   260  		return err
   261  	}
   262  	*p = v
   263  	return nil
   264  }
   265  
   266  // Float32 reads the value from the Chunk payload buffer.
   267  func (c *Chunk) Float32() (float32, error) {
   268  	v, err := c.Uint32()
   269  	if err != nil {
   270  		return 0, nil
   271  	}
   272  	return float32FromInt(v), nil
   273  }
   274  
   275  // Float64 reads the value from the Chunk payload buffer.
   276  func (c *Chunk) Float64() (float64, error) {
   277  	v, err := c.Uint64()
   278  	if err != nil {
   279  		return 0, nil
   280  	}
   281  	return float64FromInt(v), nil
   282  }
   283  
   284  // ReadBytes reads the value from the Chunk payload buffer.
   285  func (c *Chunk) ReadBytes(p *[]byte) error {
   286  	v, err := c.Bytes()
   287  	if err != nil {
   288  		return err
   289  	}
   290  	*p = v
   291  	return nil
   292  }
   293  
   294  // StringVal reads the value from the Chunk payload buffer.
   295  func (c *Chunk) StringVal() (string, error) {
   296  	b, err := c.Bytes()
   297  	if err != nil {
   298  		return "", err
   299  	}
   300  	return string(b), nil
   301  }
   302  
   303  // ReadUint16 reads the value from the Chunk payload buffer into the provided pointer.
   304  func (c *Chunk) ReadUint16(p *uint16) error {
   305  	v, err := c.Uint16()
   306  	if err != nil {
   307  		return err
   308  	}
   309  	*p = v
   310  	return nil
   311  }
   312  
   313  // ReadUint32 reads the value from the Chunk payload buffer into the provided pointer.
   314  func (c *Chunk) ReadUint32(p *uint32) error {
   315  	v, err := c.Uint32()
   316  	if err != nil {
   317  		return err
   318  	}
   319  	*p = v
   320  	return nil
   321  }
   322  
   323  // ReadUint64 reads the value from the Chunk payload buffer into the provided pointer.
   324  func (c *Chunk) ReadUint64(p *uint64) error {
   325  	v, err := c.Uint64()
   326  	if err != nil {
   327  		return err
   328  	}
   329  	*p = v
   330  	return nil
   331  }
   332  
   333  // ReadString reads the value from the Chunk payload buffer into the provided pointer.
   334  func (c *Chunk) ReadString(p *string) error {
   335  	v, err := c.StringVal()
   336  	if err != nil {
   337  		return err
   338  	}
   339  	*p = v
   340  	return nil
   341  }
   342  
   343  // ReadFloat32 reads the value from the Chunk payload buffer into the provided pointer.
   344  func (c *Chunk) ReadFloat32(p *float32) error {
   345  	v, err := c.Float32()
   346  	if err != nil {
   347  		return err
   348  	}
   349  	*p = v
   350  	return nil
   351  }
   352  
   353  // ReadFloat64 reads the value from the Chunk payload buffer into the provided pointer.
   354  func (c *Chunk) ReadFloat64(p *float64) error {
   355  	v, err := c.Float64()
   356  	if err != nil {
   357  		return err
   358  	}
   359  	*p = v
   360  	return nil
   361  }