fantomongo / fan / ObjectID.fan

////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2010 Liam Staskawicz
//
//  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.
//
////////////////////////////////////////////////////////////////////////////////

using inet
using concurrent

**
**  ObjectID
**
const class ObjectID 
{
  static const Int SIZE := 12
  private static const AtomicInt counter := AtomicInt(0)
  private const Int inc
  private const Int time
  private const Int machine
  
  new make()
  { 
    this.inc = counter.incrementAndGet().and(0xFFFFFFFF)
    this.time = DateTime.nowUnique.and(0xFFFFFFFF)
    this.machine = IpAddr.local.bytes.toDigest("MD5").readS4.and(0xFFFFFFFF)
  }
  
  new fromStream(InStream ins)
  {
    this.time = ins.readS4.and(0xFFFFFFFF)
    this.machine = ins.readS4.and(0xFFFFFFFF)
    this.inc = ins.readS4.and(0xFFFFFFFF)
  }
  
  new fromStr(Str s)
  {
    if (!isValid(s)) throw Err("invalid ObjectID format")
      
    this.time = s[0..7].toInt(16).and(0xFFFFFFFF)
    this.machine = s[8..15].toInt(16).and(0xFFFFFFFF)
    this.inc = s[16..23].toInt(16).and(0xFFFFFFFF)
  }
  
  override Str toStr()
  {
    s := StrBuf()
    [time, machine, inc].each |val, i| {
      s.add(val.toHex(8))
    }
    return s.toStr()
  }
  
  override Bool equals(Obj? o)
  {
    if (o isnot ObjectID)
      return false
    
    return ((o as ObjectID).inc == this.inc && 
            (o as ObjectID).machine == this.machine && 
            (o as ObjectID).time == this.time)
  }
  
  OutStream write(OutStream o)
  {
    return o.writeI4(time).writeI4(machine).writeI4(inc)
  }
  
  static Bool isValid(Str s)
  {
    if (s.size != 24)
      return false;
    
    // make sure it's all hex digits so we can convert to Ints
    valid := true
    s.each |Int c| {
      if (c >= '0' && c <= '9')
        return                 
      if (c >= 'a' && c <= 'f')
        return                 
      if (c >= 'A' && c <= 'F')
        return
      valid = false
    }
    return valid
  }
  
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.