Package com.massivecraft.mcore.xlib.mongodb

Source Code of com.massivecraft.mcore.xlib.mongodb.RawDBObject

// RawDBObject.java

/**
*      Copyright (C) 2008 10gen Inc.
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/

package com.massivecraft.mcore.xlib.mongodb;

import static com.massivecraft.mcore.xlib.bson.BSON.ARRAY;
import static com.massivecraft.mcore.xlib.bson.BSON.BINARY;
import static com.massivecraft.mcore.xlib.bson.BSON.BOOLEAN;
import static com.massivecraft.mcore.xlib.bson.BSON.CODE;
import static com.massivecraft.mcore.xlib.bson.BSON.CODE_W_SCOPE;
import static com.massivecraft.mcore.xlib.bson.BSON.DATE;
import static com.massivecraft.mcore.xlib.bson.BSON.EOO;
import static com.massivecraft.mcore.xlib.bson.BSON.MAXKEY;
import static com.massivecraft.mcore.xlib.bson.BSON.MINKEY;
import static com.massivecraft.mcore.xlib.bson.BSON.NULL;
import static com.massivecraft.mcore.xlib.bson.BSON.NUMBER;
import static com.massivecraft.mcore.xlib.bson.BSON.NUMBER_INT;
import static com.massivecraft.mcore.xlib.bson.BSON.NUMBER_LONG;
import static com.massivecraft.mcore.xlib.bson.BSON.OBJECT;
import static com.massivecraft.mcore.xlib.bson.BSON.OID;
import static com.massivecraft.mcore.xlib.bson.BSON.REF;
import static com.massivecraft.mcore.xlib.bson.BSON.REGEX;
import static com.massivecraft.mcore.xlib.bson.BSON.STRING;
import static com.massivecraft.mcore.xlib.bson.BSON.SYMBOL;
import static com.massivecraft.mcore.xlib.bson.BSON.TIMESTAMP;
import static com.massivecraft.mcore.xlib.bson.BSON.UNDEFINED;
import static com.massivecraft.mcore.xlib.mongodb.util.MyAsserts.assertEquals;

import java.nio.ByteBuffer;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.massivecraft.mcore.xlib.bson.BSONObject;
import com.massivecraft.mcore.xlib.bson.types.ObjectId;

/**
* This object wraps the binary object format ("BSON") used for the transport of serialized objects to / from the Mongo database.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class RawDBObject implements DBObject {

    RawDBObject( ByteBuffer buf ){
        this( buf , 0 );
        assertEquals( _end , _buf.limit() );
    }
   
    RawDBObject( ByteBuffer buf , int offset ){
        _buf = buf;
        _offset = offset;
        _end = _buf.getInt( _offset );
    }

    public Object get( String key ){
        Element e = findElement( key );
        if ( e == null )
            return null;
        return e.getObject();
    }

    public Map toMap() {
        Map m = new HashMap();
        Iterator i = this.keySet().iterator();
        while (i.hasNext()) {
            Object s = i.next();
            m.put(s, this.get(String.valueOf(s)));
        }
        return m;
    }

    public Object put( String key , Object v ){
        throw new RuntimeException( "read only" );
    }

    public void putAll( BSONObject o ){
        throw new RuntimeException( "read only" );
    }
   
    public void putAll( Map m ){
        throw new RuntimeException( "read only" );
    }

    public Object removeField( String key ){
        throw new RuntimeException( "read only" );
    }

    /**
     * @deprecated
     */
    @Deprecated
    public boolean containsKey( String key ){
        return containsField(key);
    }

    public boolean containsField( String field ){
        return findElement( field ) != null;
    }

    public Set<String> keySet(){   
        Set<String> keys = new HashSet<String>();
       
        ElementIter i = new ElementIter();
        while ( i.hasNext() ){
            Element e = i.next();
      if ( e.eoo() )
    break;
            keys.add( e.fieldName() );
        }
       
        return keys;
    }

    String _readCStr( final int start ){
  return _readCStr( start , null );
    }
   
    String _readCStr( final int start , final int[] end ){
        synchronized ( _cStrBuf ){
            int pos = 0;
            while ( _buf.get( pos + start ) != 0 ){
                _cStrBuf[pos] = _buf.get( pos + start );
                pos++;
                if ( pos >= _cStrBuf.length )
                    throw new IllegalArgumentException( "c string too big for RawDBObject.  so far[" + new String( _cStrBuf ) + "]" );

                if ( pos + start >= _buf.limit() ){
                    StringBuilder sb = new StringBuilder();
                    for ( int x=0; x<10; x++ ){
                        int y = start + x;
                        if ( y >= _buf.limit() )
                            break;
                        sb.append( (char)_buf.get( y ) );
                    }
                    throw new IllegalArgumentException( "can't find end of cstring.  start:" + start + " pos: " + pos + " [" + sb + "]" );
                }
            }
            if ( end != null && end.length > 0 )
                end[0] = start + pos;
            return new String( _cStrBuf , 0 , pos );

        }
    }

    String _readJavaString( final int start ){
  int size = _buf.getInt( start ) - 1;
 
  byte[] b = new byte[size];

  int old = _buf.position();
  _buf.position( start + 4 );
  _buf.get( b , 0 , b.length );
  _buf.position( old );
 
  try {
      return new String( b , "UTF-8" );
  }
  catch ( java.io.UnsupportedEncodingException uee ){
      return new String( b );
  }
    }

    /**
     * includes 0 at end
     */
    int _cStrLength( final int start ){
  int end = start;
  while ( _buf.get( end ) != 0 )
      end++;
  return 1 + ( end - start );
    }

    Element findElement( String name ){
        ElementIter i = new ElementIter();
        while ( i.hasNext() ){
            Element e = i.next();
            if ( e.fieldName().equals( name ) )
                return e;
        }
        return null;
    }

    public boolean isPartialObject(){
        return false;
    }


    public void markAsPartialObject(){
        throw new RuntimeException( "RawDBObject can't be a partial object" );
    }

    @Override
    public String toString(){
        return "Object";
    }
   
    class Element {
        Element( final int start ){
            _start = start;
            _type = _buf.get( _start );
            int end[] = new int[1];
            _name = eoo() ? "" : _readCStr( _start + 1 , end );
           
            int size = 1 + ( end[0] - _start); // 1 for the end of the string
            _dataStart = _start + size;

            switch ( _type ){
            case MAXKEY:
            case MINKEY:
            case EOO:
            case UNDEFINED:
            case NULL:
                break;
            case BOOLEAN:
                size += 1;
                break;
            case DATE:
            case NUMBER:
            case NUMBER_LONG:
                size += 8;
                break;
      case NUMBER_INT:
    size += 4;
    break;
            case OID:
                size += 12;
                break;
            case REF:
                size += 12;
                size += 4 + _buf.getInt( _dataStart );
                break;
            case SYMBOL:
            case CODE:
            case STRING:
                size += 4 + _buf.getInt( _dataStart );
                break;
            case CODE_W_SCOPE:
            case ARRAY:
            case OBJECT:
    size += _buf.getInt( _dataStart );
    break;
            case BINARY:
                size += 4 + _buf.getInt( _dataStart ) + 1;
                break;
            case REGEX:
    int first = _cStrLength( _dataStart );
    int second = _cStrLength( _dataStart + first );
    size += first + second;
    break;
            case TIMESTAMP:
                size += 8;
                break;
            default:
                throw new RuntimeException( "RawDBObject can't size type " + _type );
            }
            _size = size;
        }

        String fieldName(){
            return _name;
        }

        boolean eoo(){
            return _type == EOO || _type == MAXKEY;
        }
 
        int size(){
            return _size;
        }
 
        Object getObject(){
           
            if ( _cached != null )
                return _cached;
           
            switch ( _type ){
            case NUMBER:
                return _buf.getDouble( _dataStart );
      case NUMBER_INT:
    return _buf.getInt( _dataStart );
      case OID:
    return new ObjectId( _buf.getInt( _dataStart ) , _buf.getInt( _dataStart + 4 ) , _buf.getInt( _dataStart + 8 ) );
      case CODE:
            case CODE_W_SCOPE:
                throw new RuntimeException( "can't handle code" );
      case SYMBOL:
      case STRING:
    return _readJavaString( _dataStart );
      case DATE:
    return new Date( _buf.getLong( _dataStart ) );
      case REGEX:
    //int[] endPos = new int[1];
    //String first = _readCStr( _dataStart , endPos );
    //return new JSRegex( first , _readCStr( 1 + endPos[0] ) );
                throw new RuntimeException( "can't handle regex" );
      case BINARY:
    throw new RuntimeException( "can't inspect binary in db" );
      case BOOLEAN:
    return _buf.get( _dataStart ) > 0;
      case ARRAY:
      case OBJECT:
                throw new RuntimeException( "can't handle emebdded objects" );
      case NULL:
            case EOO:
      case MAXKEY:
            case MINKEY:
      case UNDEFINED:
                return null;
            }
            throw new RuntimeException( "can't decode type " + _type );
        }

        final int _start;
        final byte _type;
        final String _name;
        final int _dataStart;
        final int _size;

        Object _cached;
    }
   
    class ElementIter {
       
        ElementIter(){
            _pos = _offset + 4;
        }
       
        boolean hasNext(){
            return ! _done && _pos < _buf.limit();
        }
       
        Element next(){
            Element e = new Element( _pos );
            _done = e.eoo();
               
            _pos += e.size();
            return e;
        }
       
        int _pos;
        boolean _done = false;
    }

    final ByteBuffer _buf;
    final int _offset;
    final int _end;
    private final static byte[] _cStrBuf = new byte[1024];
}
TOP

Related Classes of com.massivecraft.mcore.xlib.mongodb.RawDBObject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.