PageRenderTime 223ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/bson/types.go

http://github.com/eclark/exl
Go | 549 lines | 463 code | 81 blank | 5 comment | 65 complexity | 839447c1374165f915f4f13e212bcfd9 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright 2011 Eric Clark. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package bson
  5. import (
  6. "bytes"
  7. "encoding/binary"
  8. "encoding/hex"
  9. "io"
  10. "os"
  11. "reflect"
  12. "strconv"
  13. )
  14. type fieldType byte
  15. const (
  16. DoubleType fieldType = iota + 1
  17. StringType
  18. DocumentType
  19. ArrayDocumentType
  20. BinaryType
  21. undefType
  22. ObjectIdType
  23. BooleanType
  24. TimeType
  25. NullType
  26. RegexType
  27. dbPointerType
  28. CodeType
  29. SymbolType
  30. ScopedCodeType
  31. Int32Type
  32. TimestampType
  33. Int64Type
  34. MinType
  35. MaxType
  36. )
  37. type BinSubtype byte
  38. const (
  39. GenericType BinSubtype = iota
  40. FunctionType
  41. OldBinaryType
  42. UUIDType
  43. MD5Type BinSubtype = 5
  44. UserType BinSubtype = 0x80
  45. )
  46. func read(r io.Reader, data ...interface{}) (n int64, err os.Error) {
  47. for _, d := range data {
  48. switch dt := reflect.NewValue(d).(type) {
  49. case *reflect.PtrValue:
  50. n += int64(binary.TotalSize(dt.Elem()))
  51. case *reflect.SliceValue:
  52. n += int64(binary.TotalSize(dt))
  53. default:
  54. panic("decode type error")
  55. }
  56. err = binary.Read(r, binary.LittleEndian, d)
  57. if err != nil {
  58. return
  59. }
  60. }
  61. return
  62. }
  63. func write(w io.Writer, data ...interface{}) (n int64, err os.Error) {
  64. for _, d := range data {
  65. n += int64(binary.TotalSize(reflect.NewValue(d)))
  66. err = binary.Write(w, binary.LittleEndian, d)
  67. if err != nil {
  68. return
  69. }
  70. }
  71. return
  72. }
  73. type Element interface {
  74. WriteTo(io.Writer) (int64, os.Error)
  75. ReadFrom(io.Reader) (int64, os.Error)
  76. }
  77. type dElement struct {
  78. Element
  79. typ fieldType
  80. Key string
  81. }
  82. type Document []dElement
  83. func (d *Document) Append(key string, value Element) {
  84. d.append(Typeof(value), key, value)
  85. }
  86. func (d *Document) append(typ fieldType, key string, e Element) {
  87. *d = append([]dElement(*d), dElement{e, typ, key})
  88. }
  89. func (d *Document) WriteTo(w io.Writer) (n int64, err os.Error) {
  90. buf := bytes.NewBuffer(nil)
  91. for _, de := range []dElement(*d) {
  92. write(buf, de.typ, []byte(de.Key), byte(0))
  93. _, err = de.WriteTo(buf)
  94. if err != nil {
  95. return
  96. }
  97. }
  98. _, err = write(buf, byte(0))
  99. if err != nil {
  100. return
  101. }
  102. n, err = write(w, int32(buf.Len()+4))
  103. if err != nil {
  104. return
  105. }
  106. m, err := io.Copy(w, buf)
  107. n += m
  108. return
  109. }
  110. func (d *Document) ReadFrom(r io.Reader) (n int64, err os.Error) {
  111. var tBytelen int32
  112. m, err := read(r, &tBytelen)
  113. n += m
  114. if err != nil {
  115. return
  116. }
  117. bufd := make([]byte, 0, tBytelen-4)
  118. buf := bytes.NewBuffer(bufd)
  119. m, err = buf.ReadFrom(r)
  120. for {
  121. if buf.Len() == 1 {
  122. break
  123. }
  124. var typ fieldType
  125. m, err = read(buf, &typ)
  126. n += m
  127. if err != nil {
  128. if err == os.EOF {
  129. break
  130. } else {
  131. return
  132. }
  133. }
  134. elem := newElement(typ)
  135. nameb, err := buf.ReadBytes(0)
  136. if err != nil {
  137. return
  138. }
  139. n += int64(len(nameb))
  140. key := string(nameb[:len(nameb)-1])
  141. m, err = elem.ReadFrom(buf)
  142. n += m
  143. if err != nil {
  144. return
  145. }
  146. d.append(typ, key, elem)
  147. }
  148. return
  149. }
  150. type ArrayDocument struct {
  151. Document
  152. }
  153. func (ad *ArrayDocument) Append(value Element) {
  154. ad.append(Typeof(value), strconv.Itoa(len(ad.Document)), value)
  155. }
  156. type Double float64
  157. func (d *Double) WriteTo(w io.Writer) (n int64, err os.Error) {
  158. return write(w, *d)
  159. }
  160. func (d *Double) ReadFrom(r io.Reader) (n int64, err os.Error) {
  161. return read(r, d)
  162. }
  163. type String string
  164. func (s *String) String() string {
  165. return string(*s)
  166. }
  167. func (s *String) WriteTo(w io.Writer) (n int64, err os.Error) {
  168. return write(w, int32(len(string(*s))+1), []byte(string(*s)), byte(0))
  169. }
  170. func (s *String) ReadFrom(r io.Reader) (n int64, err os.Error) {
  171. var l int32
  172. m, err := read(r, &l)
  173. n += m
  174. if err != nil {
  175. return
  176. }
  177. b := make([]byte, l)
  178. m, err = read(r, b)
  179. n += m
  180. if err != nil {
  181. return
  182. }
  183. *s = String(b[:len(b)-1])
  184. return
  185. }
  186. type Binary struct {
  187. Subtype BinSubtype
  188. Data []byte
  189. }
  190. func (b *Binary) WriteTo(w io.Writer) (n int64, err os.Error) {
  191. if b.Subtype == 2 {
  192. return write(w, int32(len(b.Data) + 4), b.Subtype, int32(len(b.Data)), b.Data)
  193. }
  194. return write(w, int32(len(b.Data)), b.Subtype, b.Data)
  195. }
  196. func (b *Binary) ReadFrom(r io.Reader) (n int64, err os.Error) {
  197. //TODO handle subtype 0x02
  198. var l int32
  199. m, err := read(r, &l, &b.Subtype)
  200. n += m
  201. if err != nil {
  202. return
  203. }
  204. b.Data = make([]byte, l)
  205. m, err = read(r, b.Data)
  206. n += m
  207. return
  208. }
  209. type ObjectId []byte
  210. func (o *ObjectId) FromString(s string) (err os.Error) {
  211. *o, err = hex.DecodeString(s)
  212. return
  213. }
  214. func (o *ObjectId) String() string {
  215. if *o == nil {
  216. *o = make([]byte, 12)
  217. }
  218. return hex.EncodeToString(*o)
  219. }
  220. func (o *ObjectId) WriteTo(w io.Writer) (n int64, err os.Error) {
  221. if *o == nil {
  222. *o = make([]byte, 12)
  223. }
  224. m, err := w.Write([]byte(*o))
  225. n = int64(m)
  226. return
  227. }
  228. func (o *ObjectId) ReadFrom(r io.Reader) (n int64, err os.Error) {
  229. if *o == nil {
  230. *o = make([]byte, 12)
  231. }
  232. m, err := io.ReadFull(r, []byte(*o))
  233. n = int64(m)
  234. return
  235. }
  236. type Boolean bool
  237. func False() *Boolean {
  238. b := Boolean(false)
  239. return &b
  240. }
  241. func True() *Boolean {
  242. b := Boolean(true)
  243. return &b
  244. }
  245. func (b *Boolean) WriteTo(w io.Writer) (n int64, err os.Error) {
  246. var v byte
  247. if bool(*b) == true {
  248. v = 1
  249. }
  250. return write(w, v)
  251. }
  252. func (b *Boolean) ReadFrom(r io.Reader) (n int64, err os.Error) {
  253. var v byte
  254. n, err = read(r, &v)
  255. if err != nil {
  256. return
  257. }
  258. switch v {
  259. case 0:
  260. *b = false
  261. case 1:
  262. *b = true
  263. default:
  264. err = os.NewError("bad boolean code")
  265. }
  266. return
  267. }
  268. type Time int64
  269. func (t *Time) WriteTo(w io.Writer) (n int64, err os.Error) {
  270. return write(w, *t)
  271. }
  272. func (t *Time) ReadFrom(r io.Reader) (n int64, err os.Error) {
  273. return read(r, t)
  274. }
  275. type Null struct{}
  276. func (x *Null) WriteTo(w io.Writer) (n int64, err os.Error) {
  277. return
  278. }
  279. func (x *Null) ReadFrom(r io.Reader) (n int64, err os.Error) {
  280. return
  281. }
  282. type Regex struct {
  283. Pattern string
  284. Options string
  285. }
  286. func (re *Regex) WriteTo(w io.Writer) (n int64, err os.Error) {
  287. return write(w, []byte(re.Pattern), byte(0), []byte(re.Options), byte(0))
  288. }
  289. func (re *Regex) ReadFrom(r io.Reader) (n int64, err os.Error) {
  290. var v byte
  291. b := make([]byte, 0, 16)
  292. var pe bool
  293. for {
  294. m, err := read(r, &v)
  295. n += m
  296. if err != nil {
  297. return
  298. }
  299. if v == 0 {
  300. if !pe {
  301. re.Pattern = string(b)
  302. b = b[:0]
  303. pe = true
  304. } else {
  305. re.Options = string(b)
  306. b = b[:0]
  307. return
  308. }
  309. } else {
  310. b = append(b, v)
  311. }
  312. }
  313. return
  314. }
  315. type Code struct {
  316. String
  317. }
  318. type Symbol struct {
  319. String
  320. }
  321. type ScopedCode struct {
  322. Code *Code
  323. Scope *Document
  324. }
  325. func (sc *ScopedCode) WriteTo(w io.Writer) (n int64, err os.Error) {
  326. buf := bytes.NewBuffer(nil)
  327. _, err = sc.Code.WriteTo(buf)
  328. if err != nil {
  329. return
  330. }
  331. _, err = sc.Scope.WriteTo(buf)
  332. if err != nil {
  333. return
  334. }
  335. var l int32 = int32(buf.Len()) + 4
  336. return write(w, l, buf.Bytes())
  337. }
  338. func (sc *ScopedCode) ReadFrom(r io.Reader) (n int64, err os.Error) {
  339. var l int32
  340. m, err := read(r, &l)
  341. n += m
  342. if err != nil {
  343. return
  344. }
  345. lr := io.LimitReader(r, int64(l-4))
  346. sc.Code = new(Code)
  347. m, err = sc.Code.ReadFrom(lr)
  348. n += m
  349. if err != nil {
  350. return
  351. }
  352. sc.Scope = new(Document)
  353. m, err = sc.Scope.ReadFrom(lr)
  354. n += m
  355. return
  356. }
  357. type Int32 int32
  358. func (i *Int32) WriteTo(w io.Writer) (n int64, err os.Error) {
  359. return write(w, *i)
  360. }
  361. func (i *Int32) ReadFrom(r io.Reader) (n int64, err os.Error) {
  362. return read(r, i)
  363. }
  364. type Timestamp struct {
  365. Int64
  366. }
  367. type Int64 int64
  368. func (i *Int64) WriteTo(w io.Writer) (n int64, err os.Error) {
  369. return write(w, *i)
  370. }
  371. func (i *Int64) ReadFrom(r io.Reader) (n int64, err os.Error) {
  372. return read(r, i)
  373. }
  374. type Min struct {
  375. Null
  376. }
  377. type Max struct {
  378. Null
  379. }
  380. func newElement(typ fieldType) (e Element) {
  381. switch typ {
  382. case DoubleType:
  383. e = new(Double)
  384. case StringType:
  385. e = new(String)
  386. case DocumentType:
  387. e = new(Document)
  388. case ArrayDocumentType:
  389. e = new(ArrayDocument)
  390. case BinaryType:
  391. e = new(Binary)
  392. case ObjectIdType:
  393. e = new(ObjectId)
  394. case BooleanType:
  395. e = new(Boolean)
  396. case TimeType:
  397. e = new(Time)
  398. case NullType:
  399. e = new(Null)
  400. case RegexType:
  401. e = new(Regex)
  402. case dbPointerType:
  403. panic("db pointers are not supported")
  404. case CodeType:
  405. e = new(Code)
  406. case SymbolType:
  407. e = new(Symbol)
  408. case ScopedCodeType:
  409. e = new(ScopedCode)
  410. case Int32Type:
  411. e = new(Int32)
  412. case TimestampType:
  413. e = new(Timestamp)
  414. case Int64Type:
  415. e = new(Int64)
  416. case MinType:
  417. e = new(Min)
  418. case MaxType:
  419. e = new(Max)
  420. default:
  421. panic("unknown type" + strconv.Itoa(int(typ)))
  422. }
  423. return
  424. }
  425. func Typeof(e Element) (f fieldType) {
  426. switch e.(type) {
  427. case *Double:
  428. f = DoubleType
  429. case *String:
  430. f = StringType
  431. case *Document:
  432. f = DocumentType
  433. case *ArrayDocument:
  434. f = ArrayDocumentType
  435. case *Binary:
  436. f = BinaryType
  437. case *ObjectId:
  438. f = ObjectIdType
  439. case *Boolean:
  440. f = BooleanType
  441. case *Time:
  442. f = TimeType
  443. case *Null:
  444. f = NullType
  445. case *Regex:
  446. f = RegexType
  447. //TODO something with dbPointer
  448. case *Code:
  449. f = CodeType
  450. case *Symbol:
  451. f = SymbolType
  452. case *ScopedCode:
  453. f = ScopedCodeType
  454. case *Int32:
  455. f = Int32Type
  456. case *Timestamp:
  457. f = TimestampType
  458. case *Int64:
  459. f = Int64Type
  460. case *Min:
  461. f = MinType
  462. case *Max:
  463. f = MaxType
  464. default:
  465. panic("unknown element")
  466. }
  467. return
  468. }